【CodeForces訓練記錄】Codeforces Round 984 (Div. 3)

MNNUACM_2024ZY發表於2024-11-03

訓練情況

賽後反思

A題最簡單的題愣神了,浪費了幾分鐘,其他方面正常表現

A題

相鄰的兩個差絕對值不能出現除了 \(5\)\(7\) 以外的,直接模擬即可。

#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];
	bool flag = true;
	for(int i = 2;i<=n;i++){
		int x = abs(a[i] - a[i-1]);
		if(x != 5 && x != 7) flag = false;
	}
	if(flag) cout<<"YES"<<endl;
	else cout<<"NO"<<endl;
}

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

B題

\(n\) 個貨架,\(k\) 件商品,每個貨架只擺同一種品牌的商品,所以我們統計每個品牌商品的價格和,最後取出價格和最大的前 \(n\) 個品牌的商品即可,使用優先佇列維護。

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

using namespace std;

struct node{
	int a,b;
};

bool cmp(node x,node y){
	return x.a < y.a;
}

void solve(){
	int n,k; cin>>n>>k;
	priority_queue<int> q;
	vector<node> a(k + 1);
	for(int i = 1;i<=k;i++){
		cin>>a[i].a>>a[i].b;
	}
	sort(a.begin() + 1,a.end(),cmp);
	int sum = a[1].b;
	for(int i = 2;i<=k;i++){
		if(a[i].a == a[i-1].a) sum += a[i].b;
		else q.push(sum),sum=a[i].b;
	}
	q.push(sum);
	int ans = 0;
	for(int i = 1;i<=n;i++){
		if(!q.size()) break;
		ans += q.top();
		q.pop();
	}
	cout<<ans<<endl;
}

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

C題

我們發現修改某一位只會對附近相鄰四位產生貢獻,只會有下面幾種情況

110X
?11X0
??1X00
???X100

所以我們在替換某一位的時候,先把替換位置附近的這幾種情況記錄的 1100 子串位置和個數先全部去掉,再統計。此時我們只需要維護整個字串中子串 1100 的個數即可。

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

using namespace std;

void solve(){
	string s; cin>>s;
	int n = s.size();
	vector<bool> vis(n); 
	int cnt = 0;
	for(int i = 0;i<n-3;i++){
		if(s.substr(i,4) == "1100") vis[i] = 1,cnt++;
	}
	int k; cin>>k;
	while(k--){
		int pos,v; cin>>pos>>v;
		s[pos-1] = v+'0';
		for(int i = max(0ll,pos-4);i<=min(n-1,pos-1);i++){
			if(vis[i]) vis[i] = 0,cnt--;
		}
		for(int i = max(0ll,pos-4);i<=min(n-1,pos-1);i++){
			if(s.substr(i,4) == "1100") vis[i] = 1,cnt++;
		}
		if(cnt) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
}

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

D題

主要難點是繞順時針,而且從外往裡,一共會有 \(\lfloor \frac{min(n,m)}{2} \rfloor\) 圈,迴圈挺難寫的,我們分成順時針四段四條邊寫即可,注意一下統計出現次數,首位相接也算。

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

using namespace std;

int pd(string s){
	int cnt = 0;
	int n = s.size();
	for(int i = 0;i<n-3;i++){
		if(s.substr(i,4) == "1543") cnt++;
	}
	if(s[n-3] == '1' && s[n-2] == '5' && s[n-1] == '4' && s[0] == '3') cnt++;
	if(s[n-2] == '1' && s[n-1] == '5' && s[0] == '4' && s[1] == '3') cnt++;
	if(s[n-1] == '1' && s[0] == '5' && s[1] == '4' && s[2] == '3') cnt++;
	return cnt;
}

void solve(){
	int n,m; cin>>n>>m;
	vector<string> s(n);
	vector<vector<bool>> vis(n+1,vector<bool>(m+1));
	for(int i = 0;i<n;i++) cin>>s[i];
	string t;
	int ans = 0;
	for(int i = 0;i<min(n,m)/2;i++){
		t = "";
		for(int j = i;j<=m-1-i;j++) t+=s[i][j];
		for(int j = i+1;j<=n-1-i;j++) t+=s[j][m-i-1];
		for(int j = m-1-i-1;j>=i;j--) t+=s[n-i-1][j];
		for(int j = n-1-i-1;j>=i+1;j--) t+=s[j][i];
		// cout<<t<<endl;
		ans += pd(t);
	}
	cout<<ans<<endl;
}

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

相關文章