ZOJ 3327 Friend Number

Given a positive integer x, let P(x) denotes the product of all x's digits. Two integers x and y are friend numbers if P(x) = P(y). Here comes the problem: Given a positive integer x, of course it has a lot of friend numbers, find the smallest one which is greater than x.

Input

There are multiple test cases. The first line of input is an integer T (0 < T < 230) indicating the number of test cases. Then T test cases follow. Each case is an integer x (0 < x <= 101000). You may assume that x has no leading zero.

Output

For each test case, output the result integer in a single line. You should not output a number with leading zero.

Sample Input

3
12
19
222

Sample Output

21
33

241

构造题,需要考虑的几个点

1.在非个位处有0,那么答案就是+1

2.在个位处为0,答案是+10

3.没有0,从个位起开始分解数字,直到某个位置可以构造出比该位数字大的数为止,然后从0把式子拼回去

#include<map>
#include<cmath>    
#include<queue>    
#include<vector>
#include<cstdio>    
#include<cstring>    
#include<algorithm>    
using namespace std;
#define ms(x,y) memset(x,y,sizeof(x))    
#define rep(i,j,k) for(int i=j;i<=k;i++)    
#define per(i,j,k) for(int i=j;i>=k;i--)    
#define loop(i,j,k) for (int i=j;i!=-1;i=k[i])    
#define inone(x) scanf("%d",&x)    
#define intwo(x,y) scanf("%d%d",&x,&y)    
#define inthr(x,y,z) scanf("%d%d%d",&x,&y,&z)    
typedef long long LL;
const int low(int x) { return x&-x; }
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int N = 1e3 + 10;
const int M = 1e5 + 10;
int T, n, a[N], f[N];
char s[N];

void zero(int x)
{
	int j = 1;
	rep(i, x, n)
	{
		a[i] += j;
		j = a[i] / 10;
		a[i] = a[i] % 10;
	}
	if (j) a[++n] = j;
}

void change()
{
	rep(i, 1, n)
	{
		for (int j = a[i]; j % 2 == 0; j /= 2) f[2]++;
		for (int j = a[i]; j % 3 == 0; j /= 3) f[3]++;
		for (int j = a[i]; j % 5 == 0; j /= 5) f[5]++;
		for (int j = a[i]; j % 7 == 0; j /= 7) f[7]++;
		int flag = 1;
		if (f[2] && a[i] < 2) f[2]--, a[i] = 2;
		else if (f[3] && a[i] < 3) f[3]--, a[i] = 3;
		else if (f[2] > 1 && a[i] < 4) f[2] -= 2, a[i] = 4;
		else if (f[5] && a[i] < 5) f[5]--, a[i] = 5;
		else if (f[2] && f[3] && a[i] < 6) f[2]--, f[3]--, a[i] = 6;
		else if (f[7] && a[i] < 7) f[7]--, a[i] = 7;
		else if (f[2] > 2 && a[i] < 8) f[2] -= 3, a[i] = 8;
		else if (f[3] > 1 && a[i] < 9) f[3] -= 2, a[i] = 9;
		else flag = 0;
		if (flag)
		{
			rep(j, 1, i - 1)
			{
				if (f[3] > 1) f[3] -= 2, a[j] = 9;
				else if (f[2] > 2) f[2] -= 3, a[j] = 8;
				else if (f[7]) f[7]--, a[j] = 7;
				else if (f[2] && f[3]) f[2]--, f[3]--, a[j] = 6;
				else if (f[5]) f[5]--, a[j] = 5;
				else if (f[2] > 1) f[2] -= 2, a[j] = 4;
				else if (f[3]) f[3]--, a[j] = 3;
				else if (f[2]) f[2]--, a[j] = 2;
				else a[j] = 1;
			}
			return;
		}
	}
	a[++n] = 1;
}

int main()
{
	for (inone(T); T--;)
	{
		scanf("%s", s); n = strlen(s);
		int cnt = 0;
		rep(i, 1, n) a[i] = s[n - i] - '0', cnt += a[i] == 0;
		if (cnt - (a[1] == 0)) zero(1);
		else if (a[1] == 0) zero(2);
		else ms(f, 0), change();
		per(i, n, 1) printf("%d", a[i]);
		putchar(10);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值