Friend Number ZOJ 解题报告

#include <iostream>
#include <cstring>
using namespace std;

char in[1005];

void addOne(int start)//在原来的基础上加1,位数不变
{
    int i;
    for(i=start;i>=0;i--)
    {
        in[i]++;
        if(in[i]>'9')
            in[i]='0';
        else break;
    }
    if(i==-1)
        printf("1");
}
int main()
{
    int t,i,j,index,f,len,temp,k;
    int g[2][4]={
        {2,3,5,7},{0,0,0,0}
    };
    int num[19];
    int map[10][4]={
       //2,3,5,7
        {0,0,0,0},  //0
        {0,0,0,0}, //1
        {1,0,0,0}, //2
        {0,1,0,0}, //3
        {2,0,0,0}, //4
        {0,0,1,0},   //5
        {1,1,0,0},    //6
        {0,0,0,1},            //7
        {3,0,0,0},            //8
        {0,2,0,0}            //9
    };
    scanf("%d",&t);
    getchar();
    while(t--)
    {
        gets(in);
        f=0;
        index=-1;
        len=strlen(in);
        memset(g[1],0,sizeof(g[1]));   //没有初始化!导致num溢出 Segmentation Fault
        for(i=0;i<len;i++)
            if(in[i]=='0') {
                f++;
                index=i;
                if(f>=2)
                    break;
            }
        if(f>0) {
            if(f>=2) { addOne(len-1); puts(in); continue; } //包含2个0
            else {
                if(index!=len-1) { addOne(len-1); puts(in); continue; } //包含1个零非末尾
                else { addOne(len-2); puts(in); continue; } //包含一个零末尾
            }
        }
        else {  //不包含0                                              1
            for(i=len-1;i>=0;i--)                              //2
            { //从最后一个查找 直到查到为止
                temp=in[i]-'0';
                g[1][0]+=map[temp][0];
                g[1][1]+=map[temp][1];
                g[1][2]+=map[temp][2];
                g[1][3]+=map[temp][3];
                while(++temp <10) {                       //3
                    if( map[temp][0] <= g[1][0] && map[temp][1] <= g[1][1] && map[temp][2] <= g[1][2] && map[temp][3] <= g[1][3]  )
                        break;
                }
                if(temp<10)
                {    //找到替代temp的值
                    in[i]=temp+'0';
                    g[1][0]-=map[temp][0];
                    g[1][1]-=map[temp][1];
                    g[1][2]-=map[temp][2];
                    g[1][3]-=map[temp][3];
                    memset(num,0,sizeof(num));
                    for(j=9;j>=2;) {                              //3
                        if( map[j][0] <= g[1][0] && map[j][1] <= g[1][1] && map[j][2] <= g[1][2] && map[j][3] <= g[1][3]  )
                        {
                            g[1][0]-=map[j][0];
                            g[1][1]-=map[j][1];
                            g[1][2]-=map[j][2];
                            g[1][3]-=map[j][3];
                            num[j]++;//该num数++
                        }
                        else j--;
                    }
                    k=len-1;
                    for(j=9;j>=2; ) {
                        if(num[j]-- )
                             in[k--]=j+'0'; // Segmentation Fault :num 多于 k溢出
                        else j--;
                    }
                    while(k>=i+1) { in[k--]='1'; }
                    break;
                }//if( temp<10 ) 结尾
            }//for(i=len-1;i>=0;i--) 结尾
            if(i>=0)
                puts(in);
            else { printf("1"); puts(in);}
        }   //不包含0 结束
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值