ZOJ 3327 Friend Number

构造。

(1)如果数字中带有$0$:

 1.只有个位是$0$,这种情况就是给输入的数字$+10$再输出即可。

 2.其余情况就是给输入的数字$+1$再输出即可。

(2)如果数字中没有$0$:

 从个位开始一位一位拆掉。如果发现能凑出比某一位大一点点的数字,那么剩下的高位就不动了,再从个位开始构造目前能凑出的最大数字。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-10;
void File()
{
    freopen("D:\in.txt","r",stdin);
    freopen("D:\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar();
    x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c))
    {
        x = x * 10 + c - '0';
        c = getchar();
    }
}

char s[2000];
int T,c[20],len;

void F(int x,int f)
{
    if(x==1) return ;
    else if(x==2) c[2]=c[2]+f*1;
    else if(x==3) c[3]=c[3]+f*1;
    else if(x==4) c[2]=c[2]+f*2;
    else if(x==5) c[5]=c[5]+f*1;
    else if(x==6) c[2]=c[2]+f*1, c[3]=c[3]+f*1;
    else if(x==7) c[7]=c[7]+f*1;
    else if(x==8) c[2]=c[2]+f*3;
    else if(x==9) c[3]=c[3]+f*2;
}

int G(int x)
{
    if(x==-1)
    {
        if(c[9]>=1||c[3]>=2) return 9;
        if(c[8]>=1||c[2]>=3) return 8;
        if(c[7]>=1) return 7;
        if(c[6]>=1||(c[2]>=1&&c[3]>=1)) return 6;
        if(c[5]>=1) return 5;
        if(c[4]>=1||c[2]>=2) return 4;
        if(c[3]>=1) return 3;
        if(c[2]>=1) return 2;
        return 1;
    }

    else
    {
        if(x<2&&(c[2]>=1)) return 2;
        if(x<3&&(c[3]>=1)) return 3;
        if(x<4&&(c[4]>=1||c[2]>=2)) return 4;
        if(x<5&&(c[5]>=1)) return 5;
        if(x<6&&(c[6]>=1||(c[2]>=1&&c[3]>=1))) return 6;
        if(x<7&&(c[7]>=1)) return 7;
        if(x<8&&(c[8]>=1||c[2]>=3)) return 8;
        if(x<9&&(c[9]>=1||c[3]>=2)) return 9;
    }
}



int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(s,0,sizeof s); memset(c,0,sizeof c);

        scanf("%s",s); len=strlen(s);
        for(int i=0;i<len/2;i++) swap(s[i],s[len-i-1]);

        int sum=0;
        for(int i=0;i<len;i++) if(s[i]=='0') sum++;

        if(sum==0)
        {
            bool flag=0;
            for(int i=0;i<len;i++)
            {
                F(s[i]-'0',1);
                if(G(-1)>s[i]-'0')
                {
                    flag=1;
                    int num1=G(s[i]-'0');
                    s[i]=num1+'0';
                    F(num1,-1);
                    for(int j=0;j<i;j++)
                    {
                        int num=G(-1);
                        if(num==1) break;
                        s[j]=num+'0';
                        F(num,-1);
                    }
                    break;
                }
                else s[i]='1';
            }

            if(flag==0)
            {
                s[len]='1'; len++;
                for(int i=0;i<len;i++)
                {
                    int num=G(-1);
                    if(num==1) break;
                    s[i]=num+'0';
                    F(num,-1);
                }
            }
        }

        else
        {
            int pos;
            if(sum==1&&s[0]=='0') pos=1;
            else pos=0;

            int k=1;
            for(int i=pos;i<len;i++)
            {
                int tmp=s[i]-'0';
                s[i]=((tmp+k)%10)+'0';
                k=(tmp+k)/10;
            }
            if(k!=0) s[len]=k+'0', len++;
        }

        for(int i=len-1;i>=0;i--) printf("%c",s[i]);
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/6363472.html