ZOJ Friend Number 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


Author:  CAO, Peng

Source: The 7th Zhejiang Provincial Collegiate Programming Contest



终于把这个题目做出来了,实在是不容易啊,可以说这个题目我目前想要在省赛时把它做出来几乎是不可能的,唉,真是佩服那些浙江的孩子们是怎么在比赛时过的,大神就大神。。。。。。

这个题目找到一个数和它乘积一致,但是比它大的那个最小的数。

(1):是有0存在的情况下,开头就是零,或者中间还有零,如果是10这样的数变成20就行,如果是1011这样的数,只有一个零,但不在开头,把第一个数加1就是了,如果是1001,这样的数呢?加上10,但是是倒着加的!!!!,所以变成了1002了

(2);只有一位,后面加上1.

(3)也是最不容易想的,我实在是非常佩服那些能够想出的人,找出每一位中因子2, 3 , 5,7这样的数,用prime[],来存起来,然后再进行搭配,比如说19,可以求出prime【3】=2,然后我们再传入1进行判断具有那些因子数目,当加到3时符合了,同时赋值为3,prime[3]--,但是我们的prime【3】,还没有用完,所以赋值给下一位,就是33

(4):在我的代码中inita(),所起的作用是将最后两位中最后一位小于前一位的数或者是可以求出比它大的数都求出来,赋值给hash2[],比如hash[45]=54,而hash[28]=44,这样就知道是凡是最后两位在hash里面有值的,可以不用第三种办法了,直接把hash的值赋给num就是了,唉,实在是不简单啊!!!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
string s;
int len;
int num[10004];
int re[103];
int prime[10];

void process(int n)
{

    if(n==2)
    {
        prime[2]++;
        return ;
    }
    if(n==3)
    {
        prime[3]++;
        return ;
    }
    if(n==4)
    {
        prime[2]+=2;
        return ;
    }
    if(n==5)
    {
        prime[5]++;
        return ;
    }
    if(n==6)
    {
        prime[3]++;
        prime[2]++;
        return ;
    }
    if(n==7)
    {
        prime[7]++;
        return ;
    }
    if(n==8)
    {
        prime[2]+=3;
        return ;
    }
    if(n==9)
    {
        prime[3]+=2;
        return ;
    }
}
int judge(int n)
{
    if(n==2)
    {
        if(prime[2])
        {
            prime[2]--;
            return 1;
        }
        return 0;
    }
    if(n==3)
    {
        if(prime[3])
        {
            prime[3]--;
            return 1;
        }
        return 0;
    }
    if(n==4)
    {
        if(prime[2]>=2)
        {
            prime[2]-=2;
            return 1;
        }
        return 0;
    }
    if(n==5)
    {
        if(prime[5])
        {
            prime[5]--;
            return 1;
        }
        return 0;
    }
    if(n==6)
    {
        if(prime[3]&&prime[2])
        {
            prime[2]--;
            prime[3]--;
            return 1;
        }
        return 0;
    }
    if(n==7)
    {
        if(prime[7])
        {
            prime[7]--;
            return 1;
        }
        return 0;
    }
    if(n==8)
    {
        if(prime[2]>=3)
        {
            prime[2]-=3;
            return 1;
        }
        return 0;
    }
    if(n==9)
    {
        if(prime[3]>=2)
        {
            prime[3]-=2;
            return 1;
        }
        return 0;
    }
}
int generate()
{
    if(prime[3]>=2)
    {
        prime[3]-=2;
        return 9;
    }
    if(prime[2]>=3)
    {
        prime[2]-=3;
        return 8;
    }
    if(prime[7])
    {
        prime[7]--;
        return 7;
    }
    if(prime[2]&&prime[3])
    {
        prime[2]--;
        prime[3]--;
        return 6;
    }
    if(prime[5])
    {
        prime[5]--;
        return 5;
    }
    if(prime[2]>=2)
    {
        prime[2]-=2;
        return 4;
    }
    if(prime[3])
    {
        prime[3]--;
        return 3;
    }
    if(prime[2])
    {
        prime[2]--;
        return 2;
    }
    return 1;
}
int findzero()
{
    int i;
    int count=0;
    for(i=0;i<len;i++)
    {
        if(num[i]==0)
        count++;

    }
    return count;
}
void add(int n)
{
    int i,c;
    if(n==1)
    {
        c=1;
        for(i=0;i<len;i++)
        {
            c=c+num[i];
            num[i]=c%10;
            c=c/10;
        }
        if(c)
        {
            num[len++]=c;
        }
    }
    else
    {
        c=1;
        for(i=1;i<len;i++)
        {
            c=c+num[i];
            num[i]=c%10;
            c=c/10;
        }
        if(c)
        {
            num[len++]=c;
        }

    }



}

void print()
{

    int i;
    for(i=len-1;i>=0;i--)
    {
        printf("%d",num[i]);
    }
    printf("\n");
}
void initb()
{
    int temp;
    //printf("fdsdf");
    if(re[num[1]*10+num[0]])
    {
        temp=re[num[1]*10+num[0]];
        num[0]=temp%10;
        num[1]=temp/10;
        return;
    }
    int i,j,k;
    memset(prime,0,sizeof(prime));
    int flag=1;
    for(i=0;i<len&&flag;i++)
    {
        process(num[i]);
        for(k=num[i]+1;k<=9&&flag;k++)
        {
            if(judge(k))
            {
                num[i]=k;
                flag=0;

            }
            if(flag==0)
            break;
        }

    }
    if(i==len)
    {
        num[len++]=1;
    }
    for(j=0;j<i;j++)
    {
        num[j]=generate();
    }


}
void inita()
{
    int i,j,k;
    for(i=1;i<=9;i++)
    {
        for(j=1;j<=9;j++)
        {
            memset(prime,0,sizeof(prime));
            process(i);
            process(j);
            for(k=i+1;k<=9;k++)
            {
                if(judge(k))
                {
                    re[i*10+j]=k*10+(i*j/k);
                    break;

                }
            }



        }


    }


}
int main()
{

    int t;
    scanf("%d",&t);
    while(t--)
    {

       cin>>s;
       len=s.length();
       reverse(s.begin(),s.end());
       int i,j;
       for(i=0;i<len;i++)
       {
           num[i]=s[i]-'0';
       }
       if(len==1)
       {
           printf("1%d\n",num[0]);
           continue;
       }
       int n=findzero();
       if(n)
       {

           if(n==1)
           {
               if(num[0]==0)
               {
                   add(10);
               }
               else
               add(1);
           }
           else
           add(1);
           print();
       }
       else
       {
           memset(re,0,sizeof(re));
           inita();
           initb();
           print();
       }

    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值