ZOJ-3327-Friend Number
Time Limit: 1 Second Memory Limit: 32768 KB
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
题目链接:ZOJ-3327
题目大意:找到一个最小的数满足,P(x) = P(y)。P(x) 表示 x个数位的乘积
题目思路:分三种情况讨论
1. 如果只有个位一个0,就从十位上往高位找,找不是9的,找到加1,结束。找的过程遇到9,都改为0。如果都是9,就在数字最左边加一个1。
2. 如果有0,且不是上诉情况,那就直接从个位往高位走,遇到9,变0;遇到非9 ,加1,结束。
3. 如果没有0的话,把从个位开始,素数分解,并记录所有的素数。分解完一位,就判断下分解出来的素数能不能组成比 这一位大的 个位数,能的话取最小的这个数,设这个位为id。如123 ,个位分解完,得素数3,十位分解完得素数2,这个时候可以用分解的素数有2,3,2*3=6,要比2大且最小,所以选3。 所以十位改为3,素数3的个数减1。 接下来从个位,不停地放 已经得到的素数能组成最大的数,直到id的后一位为止。
如果一直没找到id位,就直接在原来的数前面加个‘1’ 输出即可。
参考博客:here
以下是代码:
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
int pri[15] = {0};
string s;
void getprime(int n)
{
if (n == 9) pri[3] += 2;
if (n == 8) pri[2] += 3;
if (n == 7) pri[7] ++;
if (n == 6) pri[2]++,pri[3]++;
if (n == 5) pri[5] ++;
if (n == 4) pri[2] += 2;
if (n == 3) pri[3] ++;
if (n == 2) pri[2] ++;
if (n == 1) pri[1] ++;
}
int usual(int n)
{
if (n == 9 && pri[3] >= 2)
{
pri[3] -= 2;
return 1;
}
if (n == 8 && pri[2] >= 3)
{
pri[2] -= 3;
return 1;
}
if (n == 7 && pri[7] >= 1)
{
pri[7]--;
return 1;
}
if (n == 6 && pri[2] >= 1 && pri[3] >= 1)
{
pri[2]--;
pri[3]--;
return 1;
}
if (n == 5 && pri[5] >= 1)
{
pri[5]--;
return 1;
}
if (n == 4 && pri[2] >= 2)
{
pri[2] -= 2;
return 1;
}
if (n == 3 && pri[3] >= 1)
{
pri[3]--;
return 1;
}
if (n == 2 && pri[2] >= 1)
{
pri[2]--;
return 1;
}
if (n == 1) return 1;
return 0;
}
int sol()
{
if (pri[3] >= 2)
{
pri[3] -= 2;
return 9;
}
if (pri[2] >= 3)
{
pri[2] -= 3;
return 8;
}
if (pri[7] >= 1)
{
pri[7] --;
return 7;
}
if (pri[2] >= 1 && pri[3] >= 1)
{
pri[2] --, pri[3] --;
return 6;
}
if (pri[5] >= 1)
{
pri[5] --;
return 5;
}
if (pri[2] >= 2)
{
pri[2] -= 2;
return 4;
}
if (pri[3] >= 1)
{
pri[3] --;
return 3;
}
if (pri[2] >= 1)
{
pri[2] --;
return 2;
}
return 1;
}
string solve(string s)
{
int i,j;
int flag = 0;
int len = s.size();
memset(pri,0,sizeof(pri));
for (i = len - 1; i >= 0; i--)
{
getprime(s[i] - '0');
int ok = 0;
for (j = s[i] - '0' + 1; j <= 9; j++)
{
if (usual(j))
{
ok = 1;
break;
}
}
if (ok)
{
flag = 1;
s[i] = j + '0';
break;
}
}
if (flag)
{
int ii = i;
for(int i = len - 1; i > ii; i--)
{
s[i] = sol() + '0';
}
}
else
{
cout << 1;
for (int i = 0; i < s.size(); i++)
{
s[i] = sol() + '0';
}
}
return s;
}
int find_zero(string s)
{
int num = 0;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '0')
{
num++;
}
}
return num;
}
int main(){
int t;
cin >> t;
while(t--)
{
cin >> s;
int len = s.size();
int zero = find_zero(s);
if (s.size() == 1)
{
cout << 1 << s[s.size() - 1] << endl;
continue;
}
else if (!find_zero(s))
{
string ans = solve(s);
cout << ans << endl;
}
else
{
if (zero == 1 && s[s.size() - 1] == '0')
{
int cnt_9 = 0;
for (int i = len - 2; i >= 0; i--)
{
if (s[i] == '9')
{
s[i] = '0';
cnt_9++;
}
else
{
s[i]++;
break;
}
}
if (cnt_9 == len - 1)
{
cout << 1;
}
}
else
{
for (int i = len - 1; i >= 0; i--)
{
if (s[i] != '9')
{
s[i]++;
break;
}
else s[i] = '0';
}
}
cout << s << endl;
}
}
return 0;
}