1.考點
時間
1.閏年判斷
2.年,月,日判斷是否合法
3.迴文字串判斷
4.年,月,日,小時,秒的進位
2.考試成績
題目: | T1 | T2 | T3 | T4 | T5 | T6 | 總分 |
---|---|---|---|---|---|---|---|
分數: | 100 | 100 | 36 | 10 | 0 | 0 | 246 |
難度: | 入門 | 入門 | 普及- | 普及/提高- | 普及- | 普及/提高- |
3.錯誤點
T3.[藍橋杯 2017 省 B] 日期問題:寫了暴力程式碼,但是沒法補零和if判斷太多,導致最後自己也不知道哪裡出現了BUG
T4.[藍橋杯 2020 省 AB2] 迴文日期:只對了一個測試點,純屬運氣。因為解法有問題,而且只判斷了前半部分,導致後半部分是否迴文無法判斷
T5.小挖的時間/T6.2038年問題:由於當時正在改T3和T4的程式碼部分,導致最後沒有時間思考這兩道題目,所以cout
樣例就直接交上去了
4.改題
T3.[藍橋杯 2017 省 B] 日期問題
題目注意點:
1.不要暴力,用
for
迴圈一個一個迴圈出來年,月,日,時間十分充足2.檢測迴圈出來的時間能否對的上要寫一個函式,否則十分混亂
3.要補零的地方要補零
4.判斷時要把四位數字的年份變成兩位數字,因為輸入時就是兩位
補題後程式碼
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 2;
const int N1 = 1e3 + 2;
typedef long long ll;
typedef unsigned long long ull;
//#define int long long
//#define fo(i,n,m) for(int i=n;i<=m;i++)
int mouth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31},a,b,c;
bool check(int x)//閏年判斷板子
{
if((x%400==0)||(x%4==0&&x%100!=0))
{
return 1;
}
return 0;
}
bool ct(int x,int y,int z) //用ct函式判斷是否為輸入的數字
{
if(a==x&&b==y&&c==z)
{
return 1;
}
else if(c==x&&b==z&&a==y)
{
return 1;
}
else if(c==x&&b==y&&a==z)
{
return 1;
}
return 0;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
char chuhao;
cin>>a>>chuhao>>b>>chuhao>>c;
for(int i=1960;i<=2059;i++)
{
if(check(i))//判斷閏年
{
mouth[2]=29;
}
else
{
mouth[2]=28;
}
for(int j=1;j<=12;j++)
{
for(int k=1;k<=mouth[j];k++)
{
int nian=i/10%10*10+i%10;//要算出來這裡的年份,因為輸入時的年份只有兩位
if(ct(nian,j,k))
{
cout<<i<<'-'<<setw(2)<<setfill('0')<<j<<'-'<<setw(2)<<setfill('0')<<k<<'\n'; //如果只有一位數要補零
}
}
}
}
return 0;
}
T4.[藍橋杯 2020 省 AB2] 迴文日期
題目注意點
1.從一天一天來算,一秒一秒來算回超時
2.判斷ABABBABA結構和迴文結構要各寫一個函式,而且只能儲存第一個迴文日期,所以還要打上標記
3.隨時都要判斷是否可以進位
補題後程式碼
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 2;
const int N1 = 1e3 + 2;
typedef long long ll;
typedef unsigned long long ull;
//#define int long long
//#define fo(i,n,m) for(int i=n;i<=m;i++)
int mouth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int x)//閏年判斷板子
{
if((x%400==0)||(x%4==0&&x%100!=0))
{
return 1;
}
return 0;
}
bool ct(string a)//判斷是否迴文
{
string ans="";
int len=a.length();
for(int i=0;i<len;i++)
{
ans=a[i]+ans;
}
return ans==a;
}
bool huiwen(string a)//判斷是否為ABABBABA結構
{
bool f1=(a[0]==a[2])&&(a[5]==a[7])&&(a[2]==a[5]);
bool f2=(a[1]==a[3])&&(a[4]==a[6])&&(a[1]==a[4]);
return f1&&f2;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n;
cin>>n;
//算出年月日
int y=n/10000;
int m=n%10000/100;
int d=n%100;
bool flag1=0,flag2=0;//要打標記
string ans1,ans2;
while(1)//因為不知道什麼時候能找到,於是直接寫死迴圈
{
d++;
if(check(y))//判斷是否為閏年
{
mouth[2]=29;
}
else
{
mouth[2]=28;
}
//進位
if(d>mouth[m])
{
d=1;
m++;
if(m>12)
{
y++;
m=1;
}
}
//為了輸出,於是用string存起來
string x=to_string(y*10000+m*100+d);
if(!flag1&&ct(x))//如果迴文
{
ans1=x;//儲存答案
flag1=1;//打上標記,避免下次繼續
}
if(!flag2&&huiwen(x))//如果是ABABBABA結構
{
ans2=x;//儲存答案
flag2=1;//打上標記,避免下次繼續
}
if(flag1&&flag2)//假如說都被找到了
{
break;//迴圈退出
}
}
cout<<ans1<<'\n'<<ans2;//輸出
return 0;
}
T5.小挖的時間
題目注意點:
1.只有12個時間點,可以先除以\(60\*12=720\),這樣子可以省時間,否則就會TLE。
2.這裡的
check
函式要把個十百千都找出來,然後打三個tmp
來算減去的時間3.%720之前要把
t/720*31
給存進變數裡
補題後程式碼
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 2;
const int N1 = 1e3 + 2;
typedef long long ll;
typedef unsigned long long ull;
//#define int long long
//#define fo(i,n,m) for(int i=n;i<=m;i++)
bool check(int h,int m)
{
//求出個十百千
int g=m%10;
int s=m/10;
int b=h%10;
int q=h/10;
int tmp1=g-s,tmp2=s-b,tmp3=b-q;//求出差,看眼是否符合等差數列
if(q==0)//如果小時只有個位數,那隻能特判
{
if(tmp1==tmp2)
{
return 1;
}
return 0;
}
if(tmp1==tmp2&&tmp2==tmp3)//如果符合等差數列
{
return 1;
}
else
{
return 0;
}
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T,t;
cin>>T;
while(T--)
{
cin>>t;
int h=12,m=0,cnt=t/720*31;//要先存在模
t%=720;
for(int i=1;i<=t;i++)
{
m++;
//處理進位
if(m==60)
{
h++;
m=0;
}
if(h==13)
{
h=1;
}
//判斷這兩個時間符不符合等差數列
if(check(h,m))
{
++cnt;
}
}
cout<<cnt<<'\n';//由於T組資料點,於是要在迴圈內輸出
}
return 0;
}
T6.2038年問題
題目注意點:
1.要開
long long
否則會爆int
2.閏年要每個迴圈都判
3.要進位時隨時都要進位
程式碼
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int mouth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int x) {//閏年判斷板子
if ((x % 400 == 0) || (x % 4 == 0 && x % 100 != 0)) {
return 1;
}
return 0;
}
ll t, n, year, month, day, h, m, s;
int main() {
int T;//T組資料
cin >> T;
while (T--) {
t = 1;
cin >> n >> year >> month >> day >> h >> m >> s;
for (int i = 1; i < n; i++) {
t *= 2; //每次都需要乘2
}
t--;//減去第一次的1
//進位
s += t;
m += s / 60;
s %= 60;
h += m / 60;
m %= 60;
day += h / 24;
h %= 24;
//閏年
if (check(year)) {
mouth[2] = 29;
} else {
mouth[2] = 28;
}
while (day > mouth[month]) { //如果時間大於月份時間
day = day - mouth[month];
month++;
//進位
if (month == 13) {
month = 1;
year++;
if (check(year)) {//進位後要及時判閏年
mouth[2] = 29;
} else {
mouth[2] = 28;
}
}
}
cout << year << " " << month << " " << day << " " << h << " " << m
<< " " << s << endl;//輸出
}
return 0;
}
5.總結
不要一直寫暴力,要思考怎麼才能減時間。
考試時自己多想幾組HACK資料。