hdu1271整数对

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值