hdu 1271 整数对(数学+枚举+stl)

通过解析输入数字N,找出所有可能的原始数字A,使得A和其去掉任意一位后的数字B之和等于N,并按大小顺序输出。若无解,则输出Nosolution.。

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

整数对

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2673    Accepted Submission(s): 922


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.
 

Author
Gardon
 

Source
 题目分析:
这种情况下我们将一个数拆成三部分,要去掉的数字的位b,b之前的部分a,b之后的部分c,然后原数x = a*pow(k+1) + b*pow(k) + c
删掉一位后y = a*pow(k)+c
所以n = (11*a+b)*pow(k) + 2c;
首先枚举去掉的数字位
所以可以通过n/(11*pow(k))求得a,然后枚举b的值,求取c之后进行合理性判断,具体见代码
然后利用stl里的set去重排序
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>

using namespace std;


int n,a,b,c;
set<int> v;

int pow ( int n )
{
    if ( n == 0 ) return 1;
    return pow(n-1)*10;
}

int main ( )
{
    while ( ~scanf ( "%d" , &n ) , n )
    {
        v.clear();
        int len = 1;
        int temp = 1;
        while ( temp <= n ) temp*=10 , len++;
        len--;
        for ( int i = 0 ; i < len ; i++ )
        {
            int pos = pow(i);
            temp = n/pos;
            a = temp/11;
            int start = (a == 0?1:0);
            for ( b = start ; b < 10 ; b++ )
            {
                temp = n - pos*(11*a+b);
                if ( temp < 0 || temp&1 ) continue;
                c = temp/2;
                if ( c >= pos ) continue;
                v.insert ( a*pos*10+b*pos+c );
            }
        }
        bool flag = true;
        set<int>::iterator it = v.begin();
        for (  it = v.begin() ; it != v.end() ; it++ )
            if ( flag )
                printf ( "%d" , *it ),flag = false;
            else printf ( " %d" , *it );
        if ( v.size() == 0 ) printf ( "No solution." );
        puts ( "" );
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值