GMPCP 粵澳正式賽

總共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題:一起做課件

變態題,略

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章