整数对 |
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) |
Total Submission(s): 2367 Accepted Submission(s): 927 |
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. 这个数学题比较麻烦,看了题解才做出来的,代码如下
#include<iostream>
#include<string> #include<cstring> #include<iomanip> #include<cstdio> #include<algorithm> #include<vector> #include<cmath> #include<set> using namespace std; typedef long long ll; typedef vector<int> vi; typedef set<int> si; si nums; int main() { int n; while(cin>>n,n) { nums.clear(); int c2,b,a; for(int k=1;k<=n;k*=10) { c2=n%k; b=(n/k)%11; a=(n/k)/11; if(!(c2%2)&&b<10&&(b>0||a>0)) { if((c2+b*k+11*a*k)==n)////在此处进行判断是比较方便的一种做法,我因为想要直接出答案所以没这么写,结果坑了好久 nums.insert(c2/2+(b+10*a)*k); } c2=n%k+k; b-=1; a=(n/k-1)/11; if(!(c2%2)&&(b>0||a>0)) { if((c2+b*k+11*a*k)==n) nums.insert(c2/2+(b+10*a)*k); } } if(nums.size()){ set<int>::iterator it=nums.begin(); printf("%d",*it); while(++it!=nums.end()) printf(" %d",*it); printf("\n"); } else cout<<"No solution."<<endl; } return 0; } 此题若设x=abc,c为k位以前的数,b为k位上的数,a为k位之前的数,那么N==2*C+b*(k-1)+11a*(k-1),仔细分析即可,注意2*c可能出现进位并进行分类讨论
代码2:
#include<iostream>
#include<string> #include<cstring> #include<iomanip> #include<cstdio> #include<algorithm> #include<vector> #include<cmath> #include<set> using namespace std; typedef long long ll; typedef vector<int> vi; typedef set<int> si; si nums; int main() { int n=1; while(cin>>n,n) { nums.clear(); int c2,b,a; for(int k=1;k<=n;k*=10) { c2=n%k; b=(n/k)%11; a=(n/k)/11; if(!(c2%2)&&b<10&&(b>0||a>0)) { if((c2+b*k+11*a*k)==n) nums.insert(c2/2+(b+10*a)*k); } if(b>0){///错误的地方是原来此处没有判断d>0,但是这种写法从n=1开始一直到220才出现错误,手工验证难以发现,所以直接判断更为方便(加上判断条件后AC) c2=n%k+k; b-=1; a=(n/k-1)/11; if(!(c2%2)&&(b>0||a>0)) { if((c2+b*k+11*a*k)==n) nums.insert(c2/2+(b+10*a)*k); }} } if(nums.size()){ set<int>::iterator it=nums.begin(); printf("%d",*it); while(++it!=nums.end()) printf(" %d",*it); printf("\n"); } else cout<<"No solution."<<endl; } return 0; } |