出生年

在这里插入图片描述
以上是新浪微博中一奇葩贴:“我出生于1988年,直到25岁才遇到4个数字都不相同的年份。”也就是说,直到2013年才达到“4个数字都不相同”的要求。本题请你根据要求,自动填充“我出生于y年,直到x岁才遇到n个数字都不相同的年份”这句话。

输入格式:
输入在一行中给出出生年份y和目标年份中不同数字的个数n,其中y在[1, 3000]之间,n可以是2、或3、或4。注意不足4位的年份要在前面补零,例如公元1年被认为是0001年,有2个不同的数字0和1。

输出格式:
根据输入,输出x和能达到要求的年份。数字间以1个空格分隔,行首尾不得有多余空格。年份要按4位输出。注意:所谓“n个数字都不相同”是指不同的数字正好是n个。如“2013”被视为满足“4位数字都不同”的条件,但不被视为满足2位或3位数字不同的条件。

输入样例1:
1988 4

输出样例1:
25 2013

输入样例2:
1 2

输出样例2:
0 0001

最初时

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int y,n;
    int count=0;//计数器
    int year;
    char a[3000][4];//定义字符数组a,存放3000个年份
    for(int i=0;i<3000;i++)
    {
    	itoa(i+1,a[i],10);//itoa()学到了,将数值转换为字符(另有许多),在stdlib.h里面
	}//此时除了四位数年份以外所有年份都是靠左的,比如a[959]="960\0"

    scanf("%d %d",&y,&n);
    //从y开始数
    for(int j=y;j<3000;j++)
    {
        //现在开始数y后每个年份有几位数字不同
        if(a[j][0]==a[j][1])count++;
        else if(a[j][0]==a[j][2])count++;
        else if(a[j][0]==a[j][3])count++;
        else if(a[j][1]==a[j][2])count++;
        else if(a[j][1]==a[j][3])count++;
        else if(a[j][2]==a[j][3])count++;//机械劳动,有待改善

        if(4-count==n)
        {

        year=j+1;

        count=0;//计数器归零
        break;
        }
        else
        {
         count=0;   
        }

    }

    //现在年龄为year-y
    //年份的输出复杂些

    if((year>=1)&&(year<=999))
    {
        printf("%d %04d",year-y,atoi(a[year-1]));
    }
    else
    {
        printf("%d %s",year-y,a[year-1]);
    }
    system("pause");
    return 0;
}

完全就是审题失误,从题意的理解再到很多细节,错得一塌糊涂。

重新做之后

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int y,n;
    int age=0,year;
    char tem[5]={"0000"};//数字转为字符便于判断重复情况
    int num1;//计数器,记重复数
    scanf("%d %d",&y,&n);
    for(int i=y;;i++,age++)
    {
        //数字转字符
       itoa(i,tem,10);

        //判断重复情况,逆向    
        num1=0;
        if(tem[0]==tem[1])num1++;
        if(tem[0]==tem[2])num1++;
        if(tem[0]==tem[3])num1++;
        if(tem[1]==tem[2])num1++;
        if(tem[1]==tem[3])num1++;
        if(tem[2]==tem[3])num1++;
        

        if((num1==0&&n==4)||(num1==1&&n==3)||((num1==3||num1==2)&&n==2)||(num1==6&&n==1))//找到了n个数字不同的年份,它就是i
        {
            year=i;
            break;
        }
    }
    printf("%d %04d",age,year);
    system("pause");
    return 0;
}

这次本应没错了,但仍编译错误,查询PTA平台说明书时知道了:
在这里插入图片描述
我刚学到的itoa函数,还想着用它来节省功夫,但竟是明文禁止的不让用。

再改进

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char* Int2String(int num,char *str);
    int y,n;
    int age=0,year;
    char tem[5]={"0000"};//数字转为字符便于判断重复情况
    int num1;//计数器,记重复数
    scanf("%d %d",&y,&n);
    for(int i=y;;i++,age++)
    {
        //数字转字符
        Int2String(i,tem);

        //判断重复情况,逆向    
        num1=0;
        if(tem[0]==tem[1])num1++;
        if(tem[0]==tem[2])num1++;
        if(tem[0]==tem[3])num1++;
        if(tem[1]==tem[2])num1++;
        if(tem[1]==tem[3])num1++;
        if(tem[2]==tem[3])num1++;
        

        if((num1==0&&n==4)||(num1==1&&n==3)||((num1==3||num1==2)&&n==2)||(num1==6&&n==1))//找到了n个数字不同的年份,它就是i
        {
            year=i;
            break;
        }
    }
    printf("%d %04d",age,year);
    system("pause");
    return 0;
}
char* Int2String(int num,char *str)//10进制 
{
    int i = 0;//指示填充str 
    if(num<0)//如果num为负数,将num变正 
    {
        num = -num;
        str[i++] = '-';
    } 
    //转换 
    do
    {
        str[i++] = num%10+48;//取num最低位 字符0~9的ASCII码是48~57;简单来说数字0+48=48,ASCII码对应字符'0' 
        num /= 10;//去掉最低位    
    }while(num);//num不为0继续循环
    
    str[i] = '0';
    
    //确定开始调整的位置 
    int j = 0;
    if(str[0]=='-')//如果有负号,负号不用调整 
    {
        j = 1;//从第二位开始调整 
        ++i;//由于有负号,所以交换的对称轴也要后移1位 
    }
    //对称交换 
    for(;j<i/2;j++)
    {
        //对称交换两端的值 其实就是省下中间变量交换a+b的值:a=a+b;b=a-b;a=a-b; 
        str[j] = str[j] + str[i-1-j];
        str[i-1-j] = str[j] - str[i-1-j];
        str[j] = str[j] - str[i-1-j];
    } 
    
    return str;//返回转换后的值 
}

主要就是把itoa函数换了一下,改成了自己写的,这里隔空感谢一下菜鸟教程,太厉害了。
C 语言整数与字符串的相互转换

  1. itoa函数安全隐患在于:当字符数组长度不足保存结果时会导致缓冲区溢出 来源 https://www.cnblogs.com/lidabo/archive/2012/07/10/2584706.html
    这里再强调一下,字符数组一定要注意,定义的时候要多留一位,存放\0,错了不止一次。
  2. 在判断一个数字里面有几位不同的时候,一直出错
    1. 最开始直接C42,判断六次,每有重复的计数器+1,之后拿4减这个,就想得到有几位不同,这是办不到的。
    2. 实际上稍复杂点,后来改为了:用这个重复数去对应n值(不同位数),相当于一一列出,得到了有普适性的答案:
重复数几位不同
04
13
3或22
61
  1. 其他的就错在将tem数组初始化的时候,初始化为\0,这就影响了判断,比如,输入202,他会判断有三位不同,应为数组内部是\0202。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值