cf#342-D - Finals in arithmetic-构造
2016-02-15 15:50
330 查看
http://codeforces.com/contest/625/problem/D
题意:
给你一个数字字符串s,长度1e6,算是一个大数吧,让你找到一个x,使得,x加上 逆转(x)=s
例如33,能找到 12,逆转(12)=21
12+21=33
输出的x不允许有前导零,例如输出 032是错的,只能输出32,如果输出320,她的逆转是023,他们的和是320+23
其实,X和逆转X就是一对回文串啦
一开始单纯地以为是回文串啦,其实还要考虑进位的问题
如 87+78 =165 ,7+8后会进位
总得来说,我们就是要把长度为n位的一个串拆成两个长度n位的回文串
我们要尽可能让 S 的第i位和第n-1-i位相同,只有这两位相同,才可能分解出两个一样的数字构成回文串
我们令l=头,r=尾
逐个比较, 如果 s[l]==s[r] ,则l,r向中间移动一格,
否则,我们看能否通过进位使得他们相等, 对于l,它左边是已经确定的,就别动了,只考虑l的往右退位,
同样,对于r,它的右边是确定的,只考虑r-1位的退位
也就是三种情况:
1、 左边l退位, if ( s[l] -1 == s[r] )
2、右边r-1退位,r增10 if (s[l] == s[r]+10 )
3、左右同时退位 if ( s[l]-1 == s[r] +10 )
如果满足哪种情况 则作相应操作,如果都不满足 则必然不可能构造出一个X
要注意的是 当r-l==1的时候, 情况1不可能成立,也就是不只左边往右退位,而右边不进位,情况3同理
判断完整个串后,还要考虑奇偶,如果是偶数长度必然没问题,如果是奇数长度,要看 最中间的那个位的数,是否为偶数,如果为奇数,则无法分解成2个回文串
至此,对于其余的位,只需要 靠左的第i位 构造为 (S【i】+1/)2,右边第n-1-i为s【i】/2
前导零的问题:
//我们求答案的过程0abc,cba0,这种情况是合法的,但是我们要输出cba0
//我们已经尽量让奇数的一边在前面了,如果得到的答案还有前导零,表明答案是,0ab0,的情况,这种情况两个数都有前导零,显然也不合法
------------以上的构造基于,长度为n位的一个串拆成两个长度n位的回文串
还有一种情况,长度为n位的穿 是由长度 n-1的回文串构造而成
如 78+87=165 ,这时我们要特判一下
即,先把 首位1,加到第二位,变成(16)(5)
然后再按照上面的方法再判断一次, 注意第一次的判断已经改变了子串的数字,需要copy一下备份
参考代码:
题意:
给你一个数字字符串s,长度1e6,算是一个大数吧,让你找到一个x,使得,x加上 逆转(x)=s
例如33,能找到 12,逆转(12)=21
12+21=33
输出的x不允许有前导零,例如输出 032是错的,只能输出32,如果输出320,她的逆转是023,他们的和是320+23
其实,X和逆转X就是一对回文串啦
一开始单纯地以为是回文串啦,其实还要考虑进位的问题
如 87+78 =165 ,7+8后会进位
总得来说,我们就是要把长度为n位的一个串拆成两个长度n位的回文串
我们要尽可能让 S 的第i位和第n-1-i位相同,只有这两位相同,才可能分解出两个一样的数字构成回文串
我们令l=头,r=尾
逐个比较, 如果 s[l]==s[r] ,则l,r向中间移动一格,
否则,我们看能否通过进位使得他们相等, 对于l,它左边是已经确定的,就别动了,只考虑l的往右退位,
同样,对于r,它的右边是确定的,只考虑r-1位的退位
也就是三种情况:
1、 左边l退位, if ( s[l] -1 == s[r] )
2、右边r-1退位,r增10 if (s[l] == s[r]+10 )
3、左右同时退位 if ( s[l]-1 == s[r] +10 )
如果满足哪种情况 则作相应操作,如果都不满足 则必然不可能构造出一个X
要注意的是 当r-l==1的时候, 情况1不可能成立,也就是不只左边往右退位,而右边不进位,情况3同理
判断完整个串后,还要考虑奇偶,如果是偶数长度必然没问题,如果是奇数长度,要看 最中间的那个位的数,是否为偶数,如果为奇数,则无法分解成2个回文串
至此,对于其余的位,只需要 靠左的第i位 构造为 (S【i】+1/)2,右边第n-1-i为s【i】/2
前导零的问题:
//我们求答案的过程0abc,cba0,这种情况是合法的,但是我们要输出cba0
//我们已经尽量让奇数的一边在前面了,如果得到的答案还有前导零,表明答案是,0ab0,的情况,这种情况两个数都有前导零,显然也不合法
------------以上的构造基于,长度为n位的一个串拆成两个长度n位的回文串
还有一种情况,长度为n位的穿 是由长度 n-1的回文串构造而成
如 78+87=165 ,这时我们要特判一下
即,先把 首位1,加到第二位,变成(16)(5)
然后再按照上面的方法再判断一次, 注意第一次的判断已经改变了子串的数字,需要copy一下备份
参考代码:
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <set> #include <vector> #include <iostream> using namespace std; #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const __int64 inf=2147483647; const double pi=acos(-1.0); double eps=0.000001; __int64 min(__int64 a,__int64 b) {return a<b?a:b;} __int64 max(__int64 a,__int64 b) { return a<b?b:a; } int ans[200000+5]; char tm[200000+5]; int num[200000+5]; int check(int *t,int len) { int i; for (i=0;i<=len/2;i++) { int l=i; int r=len-1-i; if (t[l]==t[r]) continue; else if (t[l]-1==t[r]&&r-l!=1) ///注意相邻的时候不能只左边往右退位,而右边不进位 { t[l]--; t[l+1]+=10; } else if(t[l]-1==t[r]+10) { t[l]--; t[l+1]+=10; if (r-l==1)continue; t[r]+=10; t[r-1]--; } else if (t[l]==t[r]+10&& r-l!=1) //注意相邻 { t[r]+=10; t[r-1]--; } else return 0; } if (len%2) { if ( t[len/2]%2 || t[len/2]>18 || t[len/2]<0 ) return 0; ans[len/2]=t[len/2]/2; } for (i=0;i<len/2;i++) { if (t[i]>18 || t[i]<0 ) return 0; ans[i]=(t[i]+1)/2; ans[len-i-1]=t[i]/2; } return ans[0]>0 ; //我们求答案的过程0abc,cba0,这种情况是合法的,但是我们要输出cba0 //我们已经尽量让奇数的一bian在前面了,如果得到的答案还有前导零,表明答案是,0ab0,的情况,这种情况两个数都有前导零,显然不合法 } int main() { int i,j,k; scanf("%s",tm+1); int len=strlen(tm+1); for (i=1;i<=len;i++) num[i]=tm[i]-'0'; int flag=0; if (check(num+1,len)) flag=1; if (flag) //第一次判断成功,分解为2个长度len的回文串 { for (i=0;i<len;i++) printf("%d",ans[i]); printf("\n"); } else //第一次判断失败 { for (i=1;i<=len;i++) //恢复原字符串 num[i]=tm[i]-'0'; if (num[1]==1) //首位是1,有可能是由长度len-1的两个回文串相加而成,特判 { num[2]+=10; if (check(num+2,len-1)) flag=1; if (flag) { for (i=0;i<len-1;i++) printf("%d",ans[i]); printf("\n"); } else printf("0\n"); } else printf("0\n"); } return 0; }
相关文章推荐
- vs2010所有的服务器控件都变成了未知元素
- oracle中merge方法
- 仅需6步,教你轻易撕掉app开发框架的神秘面纱(1):确定框架方案
- UITextView,Label加载html代码
- Oracle sys 与system的区别
- Android 官方推荐 : DialogFragment 创建对话框
- nginx使用小结
- Web服务器父与子 Apache和Tomcat区别
- python 汉诺塔
- 1026. 程序运行时间(15)
- 删除目录软链接注意事项
- OpenCV二次开发 编程规范
- HDU 4160 Dolls(DAG最小路径覆盖)
- 【CSS】从牛腩中深入思考盒子模型
- send函数 & recv函数
- JMeter测试是环境搭建&功能扩展
- 详解android:scaleType属性
- Handler及原理
- Linux中iostat命令参数详解
- 虚树练习集锦