整数对
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
HDU 2006-4 Programming Contest
题目分析:
这种情况下我们将一个数拆成三部分,要去掉的数字的位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 ( "" );
}
}