ZOJ 3327(思路题)

来源:互联网 发布:sql 多表查询结果合并 编辑:程序博客网 时间:2024/05/21 09:54
题解:
给定一个很大的数,求一个比其大,且各位上的数的积相等。

情况:

 如果数字当中有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 10100using 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;}



原创粉丝点击