杭电ACM 2005: 第几天?

原题回顾

Problem Description

给定一个日期,输出这个日期是该年的第几天。

Input

输入数据有多组,每组占一行,数据格式为YYYY/MM/DD组成,具体参见sample input ,另外,可以向你确保所有的输入数据是合法的。

Output

对于每组输入数据,输出一行,表示该日期是该年的第几天。

Sample Input

1985/1/20
2006/3/12

Sample Output

20
71
下面我先贴出我的AC代码,然后在对其中做详细分析:

#include <iostream>
#include<string.h>
#include<stdlib.h>

using namespace std;

int main(void)
{
    char year[5],month[3],day[3],input_str[11];//用来存储输入的字符
    int flag=0,k=-1,j=-1;
    int int_year,int_month,int_day,sum_day=0;//用来存储整型数据
    //闰年、平年各月的天数
    int leap_month_day[]= {31,29,31,30,31,30,31,31,30,31,30,31},no_leap_day[]= {31,28,31,30,31,30,31,31,30,31,30,31};;

    //cin>>input_str这一句必须放在while判断条件里,否则会出现Output Limit Exceeded
    while(cin>>input_str)
    {
        //必须对char数组初始化,否则后面会出错
        memset(year,0,sizeof(char)*5);
        memset(month,0,sizeof(char)*3);
        memset(day,0,sizeof(char)*3);

        for(int i=0; i<strlen(input_str); i++)
        {
            if(i<4)
            {
                //取出输入字符的年份
                year[i]=input_str[i];
                continue;
            }

            if(input_str[i]=='/')
            {
                ++flag;
                continue;
            }

            if(flag==1)//flag用来判断字符'/'
            {
                //取出输入字符的月份
                month[++k]=input_str[i];
            }
            if(flag==2)
            {
                //取出输入字符的天数
                day[++j]=input_str[i];
            }
        }
        //char数组转化为int
        int_year=atoi(year);
        int_month=atoi(month);
        int_day=atoi(day);
        //根据闰年、平年计算总天数
        if(int_year%4==0&&int_year%100!=0||int_year%400==0)
        {
            //注意:这是计算到month的前一个月,然后再加上day就是总天数
            for(int h=0; h<int_month-1; h++)
            {
                sum_day+=leap_month_day[h];
            }
            sum_day+=int_day;
        }
        else
        {
            for(int h=0; h<int_month-1; h++)
            {
                sum_day+=no_leap_day[h];
            }
            sum_day+=int_day;
        }

        //输出结果
        cout<<sum_day<<endl;
        //必须重新初始化
        sum_day=0;
        flag=0;
        k=-1;
        j=-1;

    }
    return 0;
}

总的来说这道题是有点小难度的,涉及到字符串的提取。对于闰年的判断这个不是很难。首先来看一个一个函数memset();memset是计算机中C/C++语言函数。将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针。
函数原型:

void *memset(void *s, int ch, size_t n);

函数解释:将s中前n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s

memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
我在这里为什么会用到初始化操作,因为主要是在输入月份的时候有时候是输入单个数例如2,有时候会输入两个数例如20,当我们输入单个数时,就会有多申请的内存,某些编译器分配空间时,内存中默认值并不为0,在cout时候回出现乱码。这是一个要注意的地方。需要包含头文件 string.h,在这里要注意头文件string.h和头文件string的区别,不懂的话可以百度。

另一个函数就是atoi(),他是把字符串转换成长整型数的一个函数。
函数原型为:

int atoi(const char *nptr);

参数nptr字符串,如果第一个非空格字符存在,是数字或者正负号则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。否则,返回零。包含在头文件stdlib.h中。

还有一个细节问题就是cin>>input_str必须放在while()判断条件里。在上述代码已有提示,其实在输入时要做判断输入的处理的,如果没有的话,提交时候会出现Output Limit Exceeded。

主要就是上面几个难点,有疑问的请留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值