1. 程式人生 > >回文日期(兩種方法,牛客)

回文日期(兩種方法,牛客)

main mes 答案 約會 會有 style turn 回文 之間

//兩種方法,第一種是我自己的復雜無腦版,第二種是大神的方法
//@第一種:
/*
思路:每一個日期都檢驗一次(沒第二種方法好)
*/
#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; }

回文日期(兩種方法,牛客)