题解:
给定一个很大的数,求一个比其大,且各位上的数的积相等。
给定一个很大的数,求一个比其大,且各位上的数的积相等。
情况:
如果数字当中有0,故单独判断,只要将其最后一位+1,但当有且仅有一个0且0在最后一位,我们得特殊处理,不然最后一位+1,把0给去掉了,故从倒数第二位开始。
其他情况,从低位向高位遍历,记录2,3,5,7的个数,对于每个位,看是否可以用已经有的2,3,5,7的个数构成大于此数的最小数,如果存在这个数字,那么可以停止遍历,此数高位的数保持不变,低位的数:从低位遍历,用已有的2,3,5,7构造尽量大的小于10的数;如果不存在这个数字,结果的最高位为1,然后从最低位遍历。
#include<cstdlib>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<list>
#include<queue>
#include<vector>
#define ULL unsigned long long
#define LL long long
#define UI unsigned int
#define inf 0x7fffffff
#define eps 1e-7
#define N 10100
using namespace std;
int n;
char str[N];
LL z[10];//保存大数
const int x[4]= {2,3,5,7};
void add(int n)
{
for (int i=0; i<4&&n!=1; ++i )
{
while(n%x[i]==0)
{
z[x[i]]++;
n/=x[i];
}
}
}
void jian(int n)
{
for (int i=0; i<4&&n!=1; ++i )
{
while(n%x[i]==0)
{
z[x[i]]--;
n/=x[i];
}
}
}
int ok(int n)
{
if(n==1)return 1;
for (int i=0; i<4&&n!=1; ++i )
{
int num=0;
while(n%x[i]==0)
{
num++;
n/=x[i];
}
if(num>z[x[i]])return 0;
}
return 1;
}
void fun(int k)
{
for(int i=n-1;i>=k;i--)
{
for(int j=9;j>=1;j--)
if(ok(j))
{
jian(j);
str[i]=j+'0';break;
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ex.in","r",stdin);
#endif
int t;
scanf("%d%*c",&t);
while (t--)
{
scanf("%s",str);
n=strlen(str);
int num=0;
for(int i=0; i<n; i++)
if(str[i]=='0')
num++;
memset(z,0,sizeof(z));
if(num==1&&str[n-1]=='0')
{
int flag=0;
for(int i=n-2; i>=0; i--)
{
str[i]++;
if(str[i]>'9')
str[i]='0';
else
{
flag=1;
break;
}
}
if(!flag)
printf("1");
}
else if(num>=1)
{
for(int i=n-1; i>=0; i--)
{
str[i]++;
if(str[i]>'9')
str[i]='0';
else
{
break;
}
}
}
else
{
add(str[n-1]-'0');
int flag=0;
for(int i=n-2; i>=0; i--)
{
int t=str[i]-'0';
add(t);
for(int k=t+1; k<10; k++)
{
if(ok(k))
{
flag=1;
jian(k);
str[i]=k+'0';
break;
}
}
if(flag)
{
fun(i+1);
break;
}
}
if(!flag)
{
printf("1");
fun(0);
}
}
puts(str);
}
return 0;
}
本文介绍了一种算法,用于解决给定一个大数后找到下一个更大的数,且这两个数的各位数字乘积相等的问题。通过统计2、3、5、7这四个质数的个数并尝试构造符合条件的大数来实现。
1167

被折叠的 条评论
为什么被折叠?



