總共20題
官方題解
A題:Alice的祕密
AC代碼
#include<bits/stdc++.h>
using namespace std;
int isDate(int year, int month, int day)
{
if(year>2020 || year<1900) return 0;
if(month>12 || month<1) return 0;
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
return (day>=1&&day<=31);
}
if(month==4||month==6||month==9||month==11) {
return (day>=1&&day<=30);
}
if((year%4==0&&year%100!=0)||(year%400==0)){
return (day>=1&&day<=29);
}
return day>=1&&day<=28;
}
int getK(char *date)
{
if(strlen(date)!=8) return 0;
int d[8];
for(int i=0; i<8; i++){
if(date[i]>'9'||date[i]<'0') return 0;
d[i] = date[i]-'0';
}
int year = d[0]*1000 + d[1]*100 + d[2]*10 + d[3];
int month = d[4]*10 + d[5];
int day = d[6]*10 + d[7];
if(!isDate(year, month, day)) return 0;
int k=0;
for(int i=0; i<8; i++){
k += d[i];
}
while(k>9){
int sum = k;
k = 0;
while(sum>0){
k+=sum%10;
sum/=10;
}
}
return k;
}
int isMsg(char *msg)
{
int i=0;
while(msg[i]!='\0'){
if(!((msg[i]==' ') || (msg[i]<='z'&&msg[i]>='a') || (msg[i]<='Z'&&msg[i]>='A')))
return 0;
i++;
}
return 1;
}
void printMsg(char *msg, int k)
{
int i=0;
while(msg[i]!='\0'){
if(msg[i]==' ') printf("#");
else{
if(msg[i]>='a'&&msg[i]<='z')
printf("%c", (msg[i]+k-'a')%26+'a');
else printf("%c", (msg[i]+k-'A')%26+'A');
}
i++;
}
printf("\n");
}
int main()
{
char date[10];
char msg[132];
while(gets(date)!=NULL){
gets(msg)!=NULL;
int k = getK(date);
if(k==0 || !isMsg(msg)) printf("none\n");
else{
printMsg(msg, k);
}
}
return 0;
}
全 C 語言代碼,學到了合法日期的表達方法,還有題目還要判斷信息合法性
B題:今天星期幾
AC代碼
#include<stdio.h>
int isLeap(int year){
return (year%4==0&&year%100!=0)||(year%400==0);
}
int daysInMonth(int year, int month){
switch(month){
case 1: return 31;
case 2: if(isLeap(year)) return 29;
else return 28;
case 3: return 31;
case 4: return 30;
case 5: return 31;
case 6: return 30;
case 7: return 31;
case 8: return 31;
case 9: return 30;
case 10: return 31;
case 11: return 30;
case 12: return 31;
}
}
int main(){
int year, month, day, sum=0;
while(~scanf("%d %d %d", &year, &month, &day)){
sum = 0;
for(int y=2000; y<year; y++){
if(isLeap(y)) sum+=366;
else sum+=365;
}
for(int m=1; m<month; m++){
sum += daysInMonth(year, m);
}
for(int d=1; d<day; d++){
sum++;
}
printf("%d %d\n", sum/4+1, sum%4+1); //表達第幾天的方式是: 模4加1
}
return 0;
}
加天數的函數有用到 switch 很秀,學到了
C題:小明的英文作業
AC代碼
#include<stdio.h>
#include<string.h>
#include<string>
#include<map>
using namespace std;
int main(){
char *cp, line[2200], word[24];
while(gets(line)){
int sum = 0;
if(line[0] == '#') break;
else{
map<string, int> m;
cp = line;
while(*cp!='\0'){
int i = 0;
while(*cp !=' '&& *cp!='\0'){
word[i] = *cp;
i++;
cp++;
}
if (*cp==' ') cp++;
word[i] = '\0';
m[word]++; //map還可以這樣用
sum++;
}
int count = 0;
map<string,int> ::iterator it;
for(it=m.begin(); it!=m.end(); it++){
if(it->second==1) count++; //只出現1次的單詞不能少於全部單詞的一半
}
if(count*2>=sum) printf("yes\n");
else printf("no\n");
}
}
return 0;
}
指針 cp 代替數組下標判斷字符的用法很秀,學到了
D題:分三排
簡單題,略
E題:擊中目標
變態題,略
F題:序列計數
變態題,略
G題:強迫症
AC代碼
#include <iostream >
using namespace std;
int main()
{
int n = 0;
int a;
cin >> n;
cin >> a;
int repeat_element = a;
int count = 1;
for(int i = 1; i < n; i++)
{
cin >> a;
if(count == 0)
{
repeat_element = a;
}
if( repeat_element == a)
count ++;
else
count --;
}
cout << repeat_element ;
return 0;
}
重複元素大於一半,可以採用投票法,不需要排序,很強的方法
H題:新型冠狀愛情病毒
變態題,略
I題:期末表彰
簡單題,略
J題:最小特徵
AC代碼
#include<bits/stdc++.h>
#define ll long long
using namespace std;
char c[10];
ll ans,ans1,ans2,ans3;
ll lg[10];
ll pd(){
ll x=0;
for(int k=1;k<=8;k++){
x+= ( (c[9]-'0')^(c[k]-'0') )*lg[8-k];
}
return x;
}
int main(){
ll n; cin>>n;
lg[0]=1;
for(int i=1;i<=10;i++) lg[i]=lg[i-1]*2; //以這種方式存儲 2的次方會快一點
while(n--){
ans=ans1=ans2=ans3=0;
cin>>c[1]>>c[2]>>c[3]>>c[8]>>c[9]>>c[4]>>c[7]>>c[6]>>c[5];
ans=pd();
swap(c[3],c[5]); swap(c[3],c[7]); swap(c[1],c[3]);
swap(c[2],c[4]); swap(c[2],c[6]); swap(c[2],c[8]);
ans1=pd();
swap(c[3],c[5]); swap(c[3],c[7]); swap(c[1],c[3]);
swap(c[2],c[4]); swap(c[2],c[6]); swap(c[2],c[8]);
ans2=pd();
swap(c[3],c[5]); swap(c[3],c[7]); swap(c[1],c[3]);
swap(c[2],c[4]); swap(c[2],c[6]); swap(c[2],c[8]);
ans3=pd();
ans=min(ans,ans1); ans=min(ans,ans2); ans=min(ans,ans3);
cout<<ans<<endl;
}
return 0;
}
K題:項目管理
AC代碼:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int manx=1e6+5;
struct node{
ll x,y;
}a[manx];
bool cmp(node a,node b){
return a.y>b.y;
}
int main(){
ll n; cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i].x>>a[i].y;
ll ans=0,cnt=0;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
cnt+=a[i].x;
ans=max(ans,cnt+a[i].y); //學生同時執行他們項目的最長時間
}
cout<<"Project "<<n<<": "<<ans<<endl;
return 0;
}
貪心,把用時間長的安排在前面,這樣在他在工作的時間可以去給其他人安排
L題:捕魚達人
提升題,略
M題:排除危險
AC代碼
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll cnt;
map<ll,ll>vis;
int main(){
ll x,y; ll ans=0,res=0,n=0;
while(cin>>x){
if(x==-1) break;
cin>>y;
n++;
res=0;
if(vis[x]==0) res++; vis[x]++;
if(vis[y]==0) res++; vis[y]++;
ans++; cnt+=res;
if(ans==cnt){
ans--; cnt-=res;
vis[x]--; vis[y]--;
}
// cout<<ans<<" "<<cnt<<endl<<endl;
}
cout<<n-ans<<endl;
return 0;
}
根據題意模擬就可以,讓化學物品ans!=元素種類cnt
N題:圖像編碼問題
AC代碼
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int manx=1e6+5;
struct node{
ll x,val;
}a[manx];
ll k=0;
bool cmp(node a,node b){
return a.val<b.val;
}
void pd(ll l,ll r){
string sl="",sr="";
do{
if(l&1) sl+="1";
else sl+="0";
l>>=1;
}while(l);
do{
if(r&1) sr+="1";
else sr+="0";
r>>=1;
}while(r);
while(sl.size()<sr.size()) sl+="0";
while(sr.size()<sl.size()) sr+="0";
reverse(sl.begin(),sl.end());
reverse(sr.begin(),sr.end());
string s="";
for(int i=0;i<sl.size();i++)
s+=sl[i],s+=sr[i];
s.erase(0,s.find_first_not_of('0'));
ll x=1,ans=0;
if(s.size()==0){
a[k].val=ans;
return;
}
for(int i=s.size()-1;i>=0;i--){
if(s[i]=='1') ans+=x;
x*=2;
}
a[k].val=ans;
}
int main(){
ll n; cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
cin>>a[++k].x;
pd(i-1,j-1);
}
sort(a+1,a+1+k,cmp);
for(int i=1;i<=k;i++){
ll cnt=1,p=i+1;
while(p<=k&&a[i].x==a[p].x) cnt++,p++; //這種寫法還挺常見的
if(p!=k+1&&i!=k) cout<<a[i].x<<","<<cnt<<" ";
else cout<<a[i].x<<","<<cnt;
i=i+cnt-1;
}
return 0;
}
O題:軍訓值日生
提升題,略
P題:今天圖書館開了沒?
AC代碼
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int manx=1e6+5;
ll a[manx][5],dp[manx][5];
int main(){
ll n; cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=4;j++) cin>>a[i][j];
}
for(int j=1;j<=4;j++) dp[1][j]=a[1][j];
for(int i=2;i<=n;i++){
for(int j=1;j<=4;j++){
if(a[i][j])
for(int k=1;k<=4;k++){
if(j==k&&a[i-1][j]) dp[i][j]=max(dp[i][j],dp[i-1][k]);
else dp[i][j]=max(dp[i][j],dp[i-1][k]+1);
}
else
for(int k=1;k<=4;k++)
dp[i][j]=max(dp[i][j],dp[i-1][k]);
}
}
ll ans=0;
for(int i=1;i<=4;i++)
ans=max(ans,dp[n][i]);
cout<<ans<<endl;
return 0;
}
Q題:小明的體育課
簡單題,略
R題:孤獨的字符串
提升題,略
S題:鮑勃的輸入法
變態題,略
T題:一起做課件
變態題,略