回文日期(两种方法,牛客)

//两种方法,第一种是我自己的复杂无脑版,第二种是大神的方法
//@第一种:
/*
思路:每一个日期都检验一次(没第二种方法好)
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
    ll t,k,y,r,n,m;
    ll ans=0;//k为年,y为月,r为日,ans为答案
    ll s[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
    //s的第0位没有,从1到12位分别为一个月的天数
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld-%lld-%lld",&k,&y,&r);//输入初始天数
        n=k*10000+y*100+r;//把一个年份变成一个数字
        //比如1926-08-16=>八位数19260816
        scanf("%lld-%lld-%lld",&k,&y,&r);//输入结尾天数
        m=k*10000+y*100+r;
        ans=0;
        for(;n<=m;n++)//从起始日期遍历到截止日期
        {
            ll yue=n/100%10+n/1000%10*10;//计算当前月
            ll r=s[yue];//计算当前最大限度的日
            if(n%10+n/10%10*10>r)//如果日超出了
            {//比如7月有31天,现在到32天,就要减去
                n-=r;
                n+=100;//而且月份要加一
            }
            if(n/100%10+n/1000%10*10>=13)
            {//同理,如果月份超出12了
                n-=1200;//月份回归到1
                n+=10000;//年加一
            }
            if(n/10000000==n%10&&n/1000000%10==n/10%10&&n/100000%10==n/100%10&&n/10000%10==n/1000%10)
                ans++;//判断是否为回文串
        }
        printf("%lld\n",ans);
    }
    return 0;
}

//@第二种:
//感谢牛客网 Cyhlnj 的代码
//下面的代码都是复制他的,手动膜拜
/*
思路:
生成1月1日到12月31日的所有回文串八位数,不管是否合法,不管大学在不在要求内
那么一共大约会有30*12=360个数
再每个数跑一遍是否在n到m内
(降维打击,从回文串本质出发,考虑到月份一共才12个,日最多31,所以用这种方法,膜拜)
*/
#include<bits/stdc++.h>
using namespace std;
int i,j,n,m,a,b,c,sum,ans,t;
int s[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};//预备每个月日期
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d-%d-%d",&a,&b,&c);//这几行同上
        n=a*10000+b*100+c;
        scanf("%d-%d-%d",&a,&b,&c);
        m=a*10000+b*100+c;
        ans=0;
        for (i=1;i<=12;i++)//i为月从1到12
            for (j=1;j<=s[i];j++)//j为日从1到s[i]
            {
                c=(j%10)*1000+(j/10)*100+(i%10)*10+(i/10);
                //举栗子:如果现在是i为12,j为08;
                //即12月08日
                //那么c=8021相当于生成一个底朝天的数
                sum=c*10000+i*100+j;//sum=80211208
                if (sum<n||sum>m) continue;//如果这个数字不在n到m之间就下一个
                ans++;//如果在的话就ans++
                //ps:这方法太巧妙了
            }
        printf("%d\n",ans);//输出答案
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zyacmer/p/9900057.html