acm steps2.1.5(整数对)

本文解析了一道关于整数对的游戏题目,通过算法找出所有可能的答案组合,并给出了详细的实现代码。文章通过设定变量和逐步推导公式的方式,解决了如何通过给定的整数和寻找原始数字的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

整数对

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值