Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 4133 | Accepted: 1062 |
Description
Input
Output
X + Y = N
Here X, Y, and N, must be replaced with the corresponding integer numbers.
There should be exactly one space on both sides of '+' and '=' characters.
Sample Input
302
Sample Output
5
251 + 51 = 302
275 + 27 = 302
276 + 26 = 302
281 + 21 = 302
301 + 01 = 302
Source
【题意】
给出一个数N,求X+Y = N的所有数对(X,Y),X,Y有如下要求,Y是X这个数删除一位所得到的数,X不能含有前导0,但是Y可以含有前导0.
【分析】
将数分三段,可以把X看成三部分:HSL,高位H,低位L,中间被strike掉的位S
所以Y 就是HL
X = (H*10 + S)*10^i + L, (i = 0, 1, 2 ... 最多log10(N),i代表L是几位数)
Y = H*10^i + L
X + Y = (H*11 + S) * 10^i + 2*L = N
N/(10^i) = (11H+S) + 2L/(10^i),其中2L/(10^i)只可能为0和1,再加上i的不到10种取值,共20种不到的组合
所以我们通过枚举L的值,来推导出H和S。
当N是奇数的时候,只可能是删除X的最后一位得到,(原因是如果L存在,则2*L%(10^i)取余
是N的后i位,因为2*L是偶数,所以N必然四偶数)。此时变成H*11 + S = N
由于S是一个数字,其值只能是0~9,故当N%11 != 10的时候是有解的。
1.N是奇数,N%11 != 10,有一个解。
2.N是偶数,还是需要考虑删除的是最后一位的情况,该情形和奇数的是一样的。
3.当枚举L的时候,又分为两种情况,2*L有进位,和2*L无进位,
即(2*L)%(10^i) = N%(10^i)
举个例子吧:
假设L是一位数,发现N的末尾是2,
则我们可以猜测的是,L = 1, 2*L = 2, 2*L无进位
然而L = 6,也是满足条件的,2*L = 12, 2*L%(10^i) = 2,即2*L向前进了1,其余数为2.
最后这样求解还可能存在重复的结果,所以我们map去一下重
【代码】
#include<map>
#include<cstdio>
#include<iomanip>
#include<iostream>
using namespace std;
int n,H,S,L,X;map<int,int>res,ri;
int main(){
cin>>n;
for(int i=0,I=1;I<=n;i++,I*=10){
if(n%I%2) continue;
H=n/I/11;
S=n/I%11;
L=n%I/2;
if(S<=9){
X=(H*10+S)*I+L;
if(H+S) res[X]=H*I+L;
ri[X]=i;
}
L=(n%I+I)/2;
S=n/I%11-1;
if(S>=0&&L){
X=(H*10+S)*I+L;
if(H+S) res[X]=H*I+L;
ri[X]=i;
}
}
cout<<res.size()<<endl;
for(map<int,int>::iterator it=res.begin();it!=res.end();it++)
cout<<it->first<<" + "<<setw(ri[it->first])<<setfill('0')<<it->second<<" = "<<n<<endl;
return 0;
}