HDOJnbsp;nbsp;1271nbsp;nbsp;nbsp;整数对

2024-02-09 07:48
文章标签 整数 nbsp hdojnbsp 1271nbsp

本文主要是介绍HDOJnbsp;nbsp;1271nbsp;nbsp;nbsp;整数对,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1271

    这个题目的思路,是这样的我们假设数字A是这样的一个数字 a*(10^(k+1)) + b*(10^k) + c 其中 a 为任意数字,b为去掉的那一位数字,范围 [0,9] 的整数,c<10^k 。则去掉b后的数字B为 a*(10^k) + c ,而A+B的值可以用一下式子表示 (11*a+b)*(10^k) + 2*c 这个值等于 n , 我们枚举 k的值,从0到10 ,对于取定的k值,显然有一下对应 2*c = n%(10^k) 或者 2*c = n%(10^k) + 10^k ; 可以求出整数c的值,然后枚举 b的值,来确定a的值,使得a的值为整数 /..计算中可能会出现重复的结果,输出是记得要处理一下#include<iostream>
#include<algorithm>
using namespace std;
int re[100];
int main()
{
    int n,a,i,j,k,num,x,y,temp,tt;

    while(scanf("%d",&n) &&n)
    {
        num = 0,tt = 1;
        for(k =0; k <= 10; k ++)
        {
            for(j = 0; j < 2; j ++)
            {
                y = n% tt,x = n/tt;
                if(j == 1)
                    y += tt,x --;
                if(x > 0 && y % 2 == 0)
                {
                    for(i = 0; i <= 9; i ++)
                    {
                        if((x-i) == 0)
                        {
                            a = (x-i)/11;
                            temp = tt*(a*10 +i) + y/2;
                            re[num++] = temp;   
                        }
                    }
                }
            tt *= 10;
        }
        sort(re,re+num);
        if(num == 0)   
            printf("No solution.\n");
        else{
            printf("%d",re[0]);
            for(i =1; i < num; i ++)
                if(re[i] != re[i-1])    printf(" %d",re[i]);
            printf("\n");
        }
    }
    return 0;
}

******************************************************************************************

还有一种代码感觉也可以....

解题思路:插入比较

设B=Bn,Bn-1,...B2,B1   枚举是再哪个位置插入了个位数k...比如枚举是第i位后面插入了个位数k..那么得到的N=11*(Bn,Bn-1,...Bk+1)*(10^(i+1))+k*(10^i)+2*(Bk-1..B2,B1)
应该不难理解吧...题目是给出了N...那么就反过来推了..看我程序吧..注意的就是一些情况的处理..如:
推出的中间数必须是个位数(有可能得到10..那么显然这个数是要不得的.)..
末尾的(Bk-1...B2,B1)不一定就是(Nk-1...N2,N1)/2阿..有可能是(1,Nk...N2,N1)/2...就如同后缀为2的..可能是1+1=2的2..也可能是6+6=12的2..
要排除10=05+5的这种错误情况..就是前缀和中间个位数不能同时为0..
 最后..输出的时候让相同的数只输出一个...

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int N,B,k,x,y,i,m,ans[1000],num;
int main()
{
       while (~scanf("%d",&N))
       {
             if (!N) break;
             num=0;
             y=N/11; x=N;
             if (x<10) ans[++num]=y*10+x;
             i=10;
             if (N%2!=1)
             while (i<=N)
             {
                   x=(N%i)/2;
                   m=N/i;
                   y=m/11;
                   k=m;
                   if (k<10)
                   {
                         k=y*(i*10)+k*i+x;
                         ans[++num]=k;
                   }
                   x=(N%i+i)/2;
                   k=m-1;
                   if (k>=0 && (y || k))
                   {
                         k=y*(i*10)+k*i+x;
                         ans[++num]=k;
                   }
                   i*=10;
             }
             if (!num) printf("No solution.\n");
             else
             {
                   sort(ans+1,ans+1+num);
                   printf("%d",ans[1]);
                   for (i=2;i<=num;i++)
                     if (ans[i]!=ans[i-1]) printf(" %d",ans[i]);
                   printf("\n");
             }
       }
       return 0;
}

下面这一种思路与上面差不多,但又有一点点不同

******************************************************************************************

假设A中去掉的数在第k+1位,可以把A分成三部分,低位,k,和高位。

A == a + b * 10^k + c * 10^(k+1)

B == a                 c * 10^k

N == A + B == 2 * a + b * 10^k + c * 10^k * 11

其中b是一位数, b * 10^k 不会进位,用 10^k 除 N 取整就可以得到 b + 11c ,再用 11 除,商和余数就分别是 c 和 b 了。但是这里有个问题 a 是一个小于 10^k 的数没错,但是 2a 有可能产生进位,这样就污染了刚才求出来的 b + 11c 。但是没有关系,因为进位最多为 1 ,也就是 b 可能实际上是 b+1 , b 本来最大是 9 ,那现在即使是 10 ,也不会影响到除 11 求得的 c 。因此 c的值是可信的。然后根据 2a 进位和不进位两种情况,分别考虑 b 要不要 -1 ,再求 a ,验算,就可以了。

迭代k从最低位到最高位做一遍,就可以找出所有可能的 A 。

#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
 return *(int *)a-*(int *)b;
}
int main()
{
 int n,i,k,a,b,c,x[20];
 while(scanf("%d",&n)&&n)
 {
  i=0;
  for(k=1;k<=n;k*=10)
  {
   c=(n/k)/11;
   b=n/k-c*11;
   if((b!=0||c!=0)&&b<10)
   {
    a=(n-b*k-c*11*k)/2;
    if(2*a+b*k+c*11*k==n)
     x[i++]=a+b*k+c*10*k;
   }
   b--;
   if((b!=0||c!=0)&&b>=0)
   {
    a=(n-b*k-c*11*k)/2;
    if(2*a+b*k+c*11*k==n)
     x[i++]=a+b*k+c*10*k;
   }
  }
  if(i)
  {
   qsort(x,i,sizeof(x[0]),cmp);
   printf("%d",x[0]);
   for(k=1;k<i;++k)
   {
    if(x[k]!=x[k-1]) printf(" %d",x[k]);
   }
   puts("");
  }
  else printf("No solution.\n");
 }
 return 0;
}

最后还有一种用的是set,顺便鉴赏一下

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
void solve(int x,set<int> &result){
    int k,high,b2,a;
    int c,sum,b1;
    for(k=1;k<=x;k*=10){
        high=x/k;
        c=high/11;
        c*=k;
        b1=high;
        if((b1!=0||c!=0)&&b1<10){
            b1*=k;
            a=(x-b1-11*c)/2;
            if(2*a+b1+11*c==x)
                result.insert(a+b1+c*10);  
        }
        b2=high-1;
        if((b2!=0||c!=0)&&b2>=0){
            b2*=k;
            int a2=(x-b2-11*c)/2;
            if(x==2*a2+b2+11*c)
                result.insert(a2+b2+10*c);
        }
    }
}
int main(){
    int x,i;
    while(cin>>x,x){
        set<int>result;
            //set结构不仅可以排序,而且可以去除重复的
        solve(x,result);
        if(result.empty()){
            printf("No solution.\n");
        }
        else{
            set<int>::iterator it=result.begin();
            printf("%d",*it);
            while(++it!=result.end())
                printf(" %d",*it);
            printf("\n");
        }
    }
    return 0;
}

这篇关于HDOJnbsp;nbsp;1271nbsp;nbsp;nbsp;整数对的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/693603

相关文章

PTA求一批整数中出现最多的个位数字

作者 徐镜春 单位 浙江大学 给定一批整数,分析每个整数的每一位数字,求出现次数最多的个位数字。例如给定3个整数1234、2345、3456,其中出现最多次数的数字是3和4,均出现了3次。 输入格式: 输入在第1行中给出正整数N(≤1000),在第二行中给出N个不超过整型范围的非负整数,数字间以空格分隔。 输出格式: 在一行中按格式“M: n1 n2 ...”输出,其中M是最大次数,n

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

单精度浮点数按存储格式转为整数的程序

///#include<cstdio>//-----------------union int_char{unsigned char ch[4];float i;};void out_put(union int_char x)//x86是小端对其模式,即最数据的最低位存储在地址的最低位上。{printf("单精度浮点数值为:%f\n",x.i,x.i);printf("存储位置从左到右

用异或交换两个整数的陷阱

前面我们谈到了,可用通过异或运算交换两个数,而不需要任何的中间变量。 如下面: void exchange(int &a, int &b) {     a ^= b;     b ^= a;     a ^= b; } 然而,这里面却存在着一个非常隐蔽的陷阱。 通常我们在对数组进行操作的时候,会交换数组中的两个元素,如exchang(&a[i], &b[j]),

Java中等题-整数替换(力扣)

给定一个正整数 n ,你可以做如下操作: 如果 n 是偶数,则用 n / 2替换 n 。如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。 返回 n 变为 1 所需的 最小替换次数 。 示例 1: 输入:n = 8输出:3解释:8 -> 4 -> 2 -> 1 示例 2: 输入:n = 7输出:4解释:7 -> 8 -> 4 -> 2 -> 1或 7 ->

43. 1 ~ n 整数中 1 出现的次数【难】

comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9843.%201%EF%BD%9En%E6%95%B4%E6%95%B0%E4%B8%AD1%E5%87%BA%E7%8E%B0%E7%9A%84%E6%AC%A1%

【LeetCode】07.整数反转

题目要求 解题思路 这道题的难点在于怎么判断越界,我们无法直接与最大值或最小值比较,但是由于每一次我们的ret都需要乘10这个特性来使用ret与最大值或最小值除10进行比较 代码实现 class Solution {public:int reverse(int x) {int ret=0;while(x){//处理越界情况if(ret<INT_MIN/10||ret>INT_MAX

【LeetCode】08.字符串转换整数

题目要求 解题思路 本题没有难点,只需注意最大整数的比较时要切换成long long 代码实现 class Solution {public:int myAtoi(string s) {//标记正负号int flag=1;long long ret=0;int n=s.size();int i=0;//去除空格while(s[i]==' ') i++;//识别符号if(s[i]==

输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。

/*** 输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。* 思路:第一步求这两个数的异或,第二步统计异或结果中1的位数*@author: Administrator*@date: 2017-1-13 下午09:39:25*/import java.util.Scanner;public class Solution4 {public int CountDifference

【计算机组成原理】详细解读无符号整数的表示与运算

定点数的编码表示与运算 导读一、无符号整数1.1 无符号整型的取值范围1.2 数据在内存中的存储1.3 小结 二、无符号整数的运算2.1 无符号整数的加法2.2 无符号整数的减法2.3 小结 结语 导读 大家好,很高兴又和大家见面啦!!! 在上一篇内容中我们介绍了BCD码的相关内容: BCD码是用二进制编码的十进制数,通常用4位二进制数表示一位十进制数码;8421码是一种