HDU 整数对

做做数学题,锻炼一下思维。不过总感觉自己智力是硬伤。快哭了

整数对

Problem Description

Gardon和小希玩了一个游戏,Gardon随便想了一个数A(首位不能为0),把它去掉一个数字以后得到另外一个数B,他把A和B的和N告诉了小希,让小希猜想他原来想的数字。不过为了公平起见,如果小希回答的数虽然不是A,但同样能达到那个条件(去掉其中的一个数字得到B,A和B之和是N),一样算小希胜利。而且小希如果能答出多个符合条件的数字,就可以得到额外的糖果。
所以现在小希希望你编写一个程序,来帮助她找到尽可能多的解。
例如,Gardon想的是A=31,B=3 告诉小希N=34,
小希除了回答31以外还可以回答27(27+7=34)所以小希可以因此而得到一个额外的糖果。


Input

输入包含多组数据,每组数据一行,包含一个数N(1<=N<=10^9),文件以0结尾。


Output

对于每个输入的N,输出所有符合要求的解(按照大小顺序排列)如果没有这样的解,输出"No solution."


Sample Input

 
 
34 152 21 0


Sample Output

 
 
27 31 32 126 136 139 141 No solution.
题意:题目要求你求出,给定你一个Num。
1. 你可以通过Num确定两个数A,B(A的前导不为0)
2. Num = A+ B;
3. B是A中删除某一位数后所形成的新的数。
在满足了以上三个条件下的A的个数有几个。如果,不存在A则输出“No solution.”
算法分析:
该题属于数学题,且是一道需要YY的数学题。我们可以通过思考知道某一个数可以用每一位的十进制表示。例:
9998 = 8*10^0 + 9*10^1 + 9*10^2 + 9*10^3; 由此,你发现了答案了没有?反正我是发现了。你只要通过迭代k位数k次,则就能确定出答案。即,当你要删除某个数中的第k为时你可以这么表示
A = a + b*10^k + c*10^(k+1);
B = a + c*10^k;
Num = A + B;
a 表示要删除第k位的首部,b表示要删除的数,c表示要删除数的尾部。
通过整理我们回的到一个式子:Num = 2*a + b*10^k + 11*c*10^k;(因为b是要删除的一位数,所以b<= 10的,因为首位可能存在近位,所以可能为10)
我们在通过Num /10^k/ 11 = c;
不知道你懂了没有?你不懂我也没办法了,我就知道这些了。
还有就是在处理的时候要注意当b,c同时为0的时候是不成立的。因为此时2*a = Num;此时先当与k位没的删了。这个可以自己写一下程序试一试就知道了。还有就是可能存在着a的进位,因此需要对b - 1进行再次判断结论是否成立。
#include <stdio.h>
#include <stdlib.h>

int cmp(const void *a,const void *b)
{
    return *(int *)a - *(int *)b;
}

int res[1000];

void Solve(const int num,int p,int &k)
{
    int a,b,c;
    c = num/p/11;
    b = num/p - 11*c;
    if(b < 10)
    {
        a = (num - b*p - 11*c*p)/2;
        if((c != 0||b != 0)&&(num == 2*a + b*p + 11*c*p))
          res[k++] = a + b*p + c*p*10; // printf("res = %d\n",res[k-1]);
    }
    b--;
    if(b >= 0)
    {
        a = (num - b*p - 11*c*p)/2;
        if((c != 0||b != 0)&&(num == 2*a + b*p + 11*c*p))
           res[k++] = a + b*p + c*p*10; // printf("res = %d\n",res[k-1]);
    }
}
int main()
{
    int n;
    while(scanf("%d",&n),n)
    {
        int k = 0;
        for(int i = 1;i <= n;i *= 10){
            Solve(n,i,k);
        }
        qsort(res,k,sizeof(res[0]),cmp);
        if(k == 0){
           printf("No solution.\n");
        }else
        {
            int tmp = -1;
            bool first = false;
            for(int i = 0;i < k;++i){
               if(tmp != res[i]){
                  if(first) printf(" ");
                  first = true;
                  tmp = res[i];
                  printf("%d",res[i]);
               }
            }
            printf("\n");
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值