【CodeForces训练记录】Codeforces Round 984 (Div. 3)

训练情况

赛后反思

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;
}
posted @ 2024-11-03 00:50  MNNUACM_2024ZY  阅读(75)  评论(0编辑  收藏  举报