【牛客訓練記錄】中國地質大學(武漢)2024年新生賽(同步賽)

MNNUACM_2024ZY發表於2024-11-02

訓練情況

賽後反思

B題大模擬急到紅溫了,WA了四發,未考慮到部分細節情況

A題

直接輸出 \(x-1\) 即可。

#define int long long

using namespace std;

void solve(){
	int x; cin>>x;
	cout<<x-1;	
}

signed main(){
	// int T; cin>>T; while(T--)
	solve();
	return 0;
}

B題

我們使用佇列容器來記錄某一天的預約佇列,按照題目要求在每一天開始的時候優先把預約的處理掉,然後再按照時間順序處理每個使用者的請求,書的部分我們容易發現它是個棧,我們使用 stack 維護即可,處理好題目中的細節情況即可。

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int N = 3e4 + 3;

int n,m;

vector<int> r[N];
map<int,bool> rvis;
map<int,int> book;
stack<int> s;

void solve(){
	cin>>n>>m;
	for(int i = 1;i<=n;i++) s.push(i);
	int ll = 1,rr = 1;
	while(m--){
		int day,id; string opt;
		cin>>day>>opt>>id;
		rr = day;
		for(int dd = ll;dd<=rr;dd++){
			for(int i = 0;i<r[dd].size();i++){
				rvis[r[dd][i]] = 0;
				if(!s.size()) continue;
				book[r[dd][i]] = s.top();
				s.pop();
			}
		}
		ll = day+1;
		if(opt == "RESERVE"){
			int d; cin>>d;
			if(rvis[id]||book[id]){
				cout<<0<<endl;
				continue;
			}
			rvis[id] = 1;
			r[day+d].push_back(id);
			cout<<1<<endl;
		} else if(opt == "BORROW"){
			if(book[id]||s.size() == 0||rvis[id]){
				cout<<0<<endl;
				continue;
			}
			book[id] = s.top();
			cout<<s.top()<<endl;
			s.pop();
		}
		else if(opt == "RETURN"){
			if(!book[id]){
				cout<<0<<endl;
				continue;
			}
			s.push(book[id]);
			cout<<book[id]<<endl;
			book[id] = 0;
		}
		else if(opt == "QUERY"){
			cout<<book[id]<<endl;
		}
	}
}

signed main(){
	// int T; cin>>T; while(T--)
	solve();
	return 0;
}

C題

我們想要判斷答案最後能否為 \(0\),我們易知重複的與操作答案會越來越小,所以我們只需要把數列中所有元素按位與即可,判斷最後按位與的答案是否為 0 即可。

#include <bits/stdc++.h>
#define int long long

using namespace std;

void solve(){
	int n; cin>>n;
	vector<int> a(n + 1);
	for(int i = 1;i<=n;i++) cin>>a[i];
	int res = a[1];
	for(int i = 2;i<=n;i++) res &= a[i];
	if(res == 0) cout<<"Yes"<<endl;
	else cout<<"No"<<endl;	
}

signed main(){
	// int T; cin>>T; while(T--)
	solve();
	return 0;
}

E題

這題我們觀察到資料範圍較小,我們可以使用深度優先搜尋(DFS)列舉出所有的技能釋放方案,再直接模擬即可,最後答案取大值。

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int N = 100;

int n,a;
int d[N],c[N],last[N];
int ans = 0;

void pd(){
	// c[1] = 4,c[2] = 1,c[3] = 2,c[4] = 4,c[5] = 3;
	int res = 0;
	int nq = 0;
	int flag = 0;
	for(int i = 1;i<=n;i++){
		if(c[i] == 1){
			if(flag == i) res+=2*d[i];
			else res+=d[i];
		}
		else if(c[i] == 2) nq+=a;
		else if(c[i] == 3){
			if(flag == i) res+=2*nq;
			else res+=nq;
		}
		else if(c[i] == 4) flag = i+1;
		// cout<<res<<endl;
	}
	ans = max(ans,res);
}

void dfs(int x){
	if(x > n){
		// for(int i = 1;i<=n;i++) cout<<c[i]<<" ";
		// cout<<endl;
		pd();
		return;
	}
	for(int i = 1;i<=4;i++){
		if(x-last[i]<=2) continue;
		c[x] = i;
		int tmp = last[i];
		last[i] = x;
		dfs(x + 1);
		c[x] = 0;
		last[i] = tmp;
	}
}

void solve(){
	cin>>n>>a;
	for(int i = 1;i<=n;i++) cin>>d[i];
	for(int i = 1;i<=4;i++) last[i] = -10;
	// pd();
	dfs(1);	
	cout<<ans<<endl;
}

signed main(){
	// int T; cin>>T; while(T--)
	solve();
	return 0;
}

G題

我們觀察題目可知,需要求區間 \([l,r]\) 偶數的個數,資料範圍允許遍歷,我們直接遍歷判斷即可。

#include <bits/stdc++.h>
#define int long long

using namespace std;

void solve(){
	int l,r; cin>>l>>r;	
	int ans = 0;
	for(int i = l;i<=r;i++){
		if(i%2==0) ans++;
	}
	cout<<ans<<endl;
}

signed main(){
	// int T; cin>>T; while(T--)
	solve();
	return 0;
}

H題

首先題數相同,我們只需要記錄字串的長度的出現次數即可,設同一透過題數的隊伍數為 \(n\),顯然所有罰時的排列組合為 \(n!\),最後我們乘法原理即可算出最終答案。

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int mod = 1e9 + 7;

int cnt[507];

int jc(int x){
	int ans = 1;
	for(int i = 1;i<=x;i++) ans*=i,ans%=mod;
	return ans%mod;
}

void solve(){
	int n; cin>>n;
	for(int i = 1;i<=n;i++){
		string s; cin>>s;
		cnt[s.size()]++;
	}	
	int ans = 1;
	for(int i = 1;i<=26;i++){
		if(!cnt[i]||cnt[i]==1) continue;
		ans *= jc(cnt[i]);
		ans %= mod;
	}
	cout<<ans<<endl;
}

signed main(){
	// int T; cin>>T; while(T--)
	solve();
	return 0;
}

L題

我們發現每次操作都會刪掉前面兩個元素,所以我們要最後留下的數最大,我們必須在刪掉之前把它移到最後面去,長度為 \(n\) 需要刪 \(\lfloor \frac{n}{2} \rfloor\) 次,每次相鄰元素交換可以將某個元素往右移動一位,所以我們只需要求區間 \([\lfloor \frac{n}{2} \rfloor,n]\) 之間最大的元素即可。

#include <bits/stdc++.h>
#define int long long

using namespace std;

void solve(){
	int n; cin>>n;
	vector<int> a(n + 1);
	for(int i =1 ;i<=n;i++) cin>>a[i];
	int ma = 0;
	int lim = n/2;
	for(int i = n-lim;i<=n;i++) ma = max(ma,a[i]);
	cout<<ma<<endl;	
}

signed main(){
	// int T; cin>>T; while(T--)
	solve();
	return 0;
}

相關文章