http://acm.hdu.edu.cn/showproblem.php?pid=1271
没有思路,上网看了题解,解法都是差不多。
引用别人的思路:
首先假设X的第k位拿走,然后加上加上X的和正好等于N!
这样的话 我们可以把X 分解成:X= a+b * 10^k +c * 10^( k+1 ); 这里特别强调一下, a代表的是比第k位后面的低位数子,可能是多位,b仅仅代表一个数值,即你选择拿开的那位数,c代表的是比k位高的高位数字,例如:12345 您想拿走3的话
这时候a=45,c=12,b=3; 然后拿走之后就会组合成另一个数:Y=a + c * 10^k; 然后X+Y=2 * a + b * 10 ^k +11 * c * 10^k;
现在如果N=X+Y;他必定满足上面那种结构!
A == a + b * 10^k + c * 10^(k+1)
B == a + c * 10^k
N == A + B == 2 * a + b * 10^k + c * 10^k * 11
其中b是一位数,b * 10^k不会进位,用10^k除N取整就可以得到b + 11c,再用11除,商和余数就分别是c和b了。但是这里有个问题a是一个小于10^k的数没错,但是2a有可能产生进位,这样就污染了刚才求出来的b + 11c。但是没有关系,因为进位最多为1,也就是b可能实际上是b+1,b本来最大是9,那现在即使是10,也不会影响到除11求得的c。因此c的值是可信的。然后根据2a进位和不进位两种情况,分别考虑b要不要-1,再求a,验算,就可以了。
迭代k从最低位到最高位做一遍,就可以找出所有可能的A。
还有一点需要注意的就是:如果结果为5002,那么可能会输入2次502.第一次去掉十位上的0,第二次去掉百位上的0,这算重复,需要去重。。。。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{int a,b,c,n;
int ans[105];
while(cin>>n&&n)
{
int count=0;
for(int k=1;k<=n;k*=10)
{
c=(n/k)/11;
b=(n/k)%11;
if((b+c)!=0&&b<10)
{
a=(n-b*k-11*c*k)/2;
if(n==2*a+b*k+11*c*k)
ans[count++]=a+b*k+10*c*k;
}
b--;
if((b+c)!=0&&b>=0)
{
a=(n-b*k-11*c*k)/2;
if(n==2*a+b*k+11*c*k)
ans[count++]=a+b*k+10*c*k;
}
}
if(count==0)
cout<<"No solution."<<endl;
else
{
sort(ans,ans+count);
cout<<ans[0];
for(int i=1;i<count;i++)
{
if(ans[i]!=ans[i-1])
cout<<" "<<ans[i];
}
cout<<endl;
}
}
return 0;
}