HDOJ 1554 Pairs of integers

来源:互联网 发布:清空datagridview数据 编辑:程序博客网 时间:2024/06/05 04:41

题目大意是:

给定一个数N(10 ……10^9),求出A,B,A的开头数字不能为0,B的开头数字可以为0,B为A去掉一个10进制位后得到的数字

及A的数位一定是B的数位+1,并且A + B = N


我们可以遍历,去掉A的第pre位后得到B,

我们假设pre位前面的为x,pre位为y,pre位后为z

即A 为 xyz,那么B为xz

这个时候y的权为flag = 10^pre

因为A + B = N

所以xy * flag  + x * flag + 2 * z = N

所以一定满足(N - 2 * z)% flag == 0;(对z的遍历初始化z = (N - N / flag* flag) / 2,并每次z+=flag/2,可以保证这个条件成立并使算法复杂度降到很低,注意当N为奇数时

该条件基本上不成立,但是当flag = 1及去掉的就是各位的时候可以成立)


并且x,y中至少有一个不为0,所以(N - 2 * z) >= flag;

并且N - 2 * z >0;

并且z是比权flag要小的

并且因为y是要被去掉的数字,所以y一定不能大于10

因为xy * flag  + x * flag + 2 * z = N         =》      x = (N - 2 * z) / 11;   Y = (N - 2 * z) % 11;


根据以上的这些条件就可以算出所有符合条件的A,B

但还是要注意结果中有重复的比如12 = 11 + 1;可以从11中去掉十位得到1,还可以从11中去掉各位得到1

所以结果中有重复,需去重

结合我的代码再次分析

我的代码:

#include<stdio.h>int stack[1001];int snum;int add(int x, int y, int z, int pre)//xyz即为答案,注意z的位数为pre-1{int i, array[11];array[pre] = y;              //y是确定的第pre为for(i = 1; i < pre; i ++)    //z是pre后面的数字{array[i] = z % 10;z /= 10;}for(i = pre + 1; i <= 10; i ++)//{array[i] = x % 10;x /= 10;}stack[++ snum] = 0;          //算出结果存如栈中for(i = 10; i >= 1; i --){stack[snum] *= 10;stack[snum] += array[i];}return 0;}int Max(int a, int b){return a > b ? a : b;}int find(int pre, int n){int i;int flag = 1;int max;if(pre == 0)return 0;for(i = 1; i < pre; i ++)     //算出权值flag *= 10;if(pre != 1 && n % 2 == 0 || pre == 1)//只有当flag = 1和n不为奇数的时候才能保证(N - 2 * z)% flag == 0;{max = Max(flag / 2, 1);for(i = (n - n / flag * flag) / 2; i < flag; i += max)//在(N - 2 * z)% flag == 0的前提下,只有z+=flag*2才能继续满足条件{if(i * 2 >= n)break;if((n - i * 2) < flag)break;if((n - i * 2) / flag % 11 != 10){add((n - i * 2) / flag / 11, (n - i * 2) / flag % 11, i, pre);//算出了x,y,z,加入栈}}}return find(pre - 1, n);}int swap(int &a, int &b){a ^= b;b ^= a;a ^= b;return 0;}int sort(){int i, j;for(i = 1; i < snum; i ++)for(j = i + 1; j <= snum; j ++){if(stack[i] == stack[j])//存在相同答案就去掉相同答案{stack[j] = stack[snum];snum --;j --;}}for(i = 1; i <= snum; i ++)          //排序{for(j = i + 1; j <= snum; j ++){if(stack[i] > stack[j]){swap(stack[i], stack[j]);}}}return 0;}int prin(int x, int n){int y = n - x, i;       //由A算出B,但是B的位数一定要有A的位数-1,否则前面补0int array[11], tail = 0;printf("%d + ", x);while(x >= 10){array[++ tail] = y % 10;y /= 10;x /= 10;}for(i = tail; i >= 1; i --)printf("%d", array[i]);printf(" = %d\n", n);return 0;}int main(){int n;int i;while(scanf("%d", &n) != EOF){snum = 0;find(10, n);    //从去掉第10为开始找sort();printf("%d\n", snum);    //坑爹的地方,因为总数没输出导致我一直wa,调试了好久,唉for(i = 1; i <= snum; i ++){prin(stack[i], n);}}return 0;}