重新振作第二天-----2024csp/j普及組題解

菜dog的日常生活發表於2024-11-12

目錄
  • 第一題:撲克牌 (簡單思維)
  • 第二題:地圖探險 (簡單模擬)
  • 第三題:小木棍 (思維)
  • 第四題:接龍 (DP)

第一題:撲克牌 (簡單思維)

題意介紹:給出n張牌不同花色的牌,每一張牌由兩個字元組成,第一個代表花色,第二個代表的是牌面數字,詢問還需要多少張牌才可以湊齊一副完整的撲克。

資料範圍:n<=52

思路:因為每一張牌都是獨一無二的,那我們只需要用map去重一下即可,然後用52減去去重後的數量即可。

複雜度:O(n)

程式碼實現:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	map<string,int>mp;
	string s;
	for(int i=1;i<=n;i++){
		cin>>s;
		mp[s]++;
	}
	int ans=52;
	ans-=mp.size();
	cout<<ans<<endl;
}

第二題:地圖探險 (簡單模擬)

題意介紹:給出T組資料,首先給出n,m,k,分別表示地圖的行列,以及機器人可以移動的次數,然後給出x,y,d分別表示機器人最開始的座標和朝向。接著,給出n行字元,每行有m個,代表著地圖中的情況,如果是“.”,則代表可以走,若是“x”,則代表不能走。根據不同的朝向,機器人採取不同的行走,d=0,則y+1;d=1,則x+1;d=2,則y-1;d=3,則x+1。在這期間,如果機器人超過了地圖的範圍的話,或者無法行走的話,則向右轉,d=(d+1)%4,則要求找出機器人所經過的格子數目。

資料範圍:n<=1E3,m<=1E3,k<=1E6

思路:直接跟著題目說的,模擬一下,也沒有用到什麼最佳化之類的。

複雜度:O(max(k,n*m))

程式碼實現:

#include<bits/stdc++.h>
using namespace std;
char a[2000][2000];
int vis[2000][2000];
void solve(){
	int n,m,k;
	cin>>n>>m>>k;
	int x,y,d;
	cin>>x>>y>>d;
	memset(vis,0,sizeof vis);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	vis[x][y]=1;
	for(int i=1;i<=k;i++){
		if(d==0){
			if(y+1>m||a[x][y+1]=='x'){
				d=(d+1)%4;
			}
			else {
				y+=1;
			}
		}
		else if(d==1){
			if(x+1>n||a[x+1][y]=='x'){
				d=(d+1)%4;
			}
			else {
				x+=1;
			}			
		}
		else if(d==2){
			if(y-1<1||a[x][y-1]=='x'){
				d=(d+1)%4;
			}
			else {
				y-=1;
			}
		}
		else if(d==3){
			if(x-1<1||a[x-1][y]=='x'){
				d=(d+1)%4;
			}
			else {
				x-=1;
			}			
		}
		vis[x][y]=1;
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(vis[i][j])
			ans++;
		}
	}
	cout<<ans<<endl;	
}
int main(){
	int t;
	cin>>t;
	while(t--)
	solve();
}

第三題:小木棍 (思維)

題意介紹:給出n根木棍,要求木棍全部用完的情況下,輸出所組成的不包含前置0的最小正數是多少。如果無法不存在,則輸出-1。

資料範圍:n<=1E5

思路:首先,根據價效比而言,優先考慮的是數字的位數,數字位數越少,值越小。因為8所消耗的木棍是最多的,所以我們肯定能組成的8越多越好。在這個大前提下,我們看能否拆掉前面的8,使得在位數不變的情況下,使得數字最小。而要求數字最小的時候,其實我們最多隻能拆2個8。因為我們考慮比8小的數字所拆的木棍,有2,5,4,6,7這五種可能,如果我們拆了更多的8,則會多出更多的木棍,但是我們不能形成更多的位數,因此可以先縮小拆的8在5及以內。因為只有除以8之後剩下的木棍大於0,我們才會有拆的情況,而加上木棍數後的數量又不能超過6,則只能是5,但是我們要求所組成的數字最小,則小數字所節省的木棍肯定後續得使用。由此,當我們計算到20個的時候,就可以得到,後面即使再進行拆分,也無法使得第一個數字比前面的小。因此只需要前20個打表,後續直接加上若干個8即可。

複雜度:O(n)

程式碼實現:

#include<bits/stdc++.h>
using namespace std;
void solve(){
	int n;
	cin>>n;
	int ans[23]={-1,-1,1,7,4,2,6,8,10,18,22,20,28,68,88,108,188,200,208,288,688};
	int x=n/7;
	int y=n%7;
	// 1:2
	// 2:5  3:5  5:5
	// 4:4
	// 0:6  6:6  9:6
	// 7:3
	// 8:7
	if(x>1){
		x-=2;
		y+=14;
		cout<<ans[y];
		while(x--){
			cout<<8;
		}
		cout<<endl;
	}
	else {
		y+=x*7;
		cout<<ans[y]<<endl;
	}
}
int main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
}

第四題:接龍 (DP)

暫無

相關文章