Kevinrzy103874的博客

Kevinrzy103874的博客

动态线条
动态线条end
code: {

专注于分享信息学竞赛技巧、知识点、模拟赛及一些题目题解,又有着当码农的乐趣,有时还会写写比赛游记等等。

模拟赛SXJ202507300900比赛记录&题解

题目请看

T1

跟着题目进行模拟,关键在于匹配字符串。

输出要用mod进行优化一下回使代码更加简洁。

贴一下代码
#include <bits/stdc++.h>
using namespace std;
#define fre(c) freopen(c".in","r",stdin);freopen(c".out","w",stdout);
#define ll long long
#define endl "\n"
#define ios ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define cst const
cst int N = 50 + 5;
int n;
bool flag[27];
char zm[28] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string s[N], str;
ll read() {
	char c;
	ll sum = 0;
	int f = 1;
	c = getchar();
	while (!isdigit(c)) {
		if (c == '-')
			f *= -1;
		c = getchar();
	}
	while (isdigit(c)) {
		sum = sum * 10 + (c - '0');
		c = getchar();
	}
	return sum * f;
}
int main() {
	ios
//	fre("1")
	cin >> n;
	for (int i = 1; i <= n; i ++) {
		cin >> s[i];
	}
	cin >> str;
	for (int i = 1; i <= n; i ++) {
		bool kmp = true;
		for (int j = 0; j < str.size(); j ++) {
			if (str[j] != s[i][j]) {
				kmp = false;
			}
		}
		if (kmp) {
			if (s[i][str.size()] >= 'A' && s[i][str.size()] <= 'Z') {
				flag[s[i][str.size()] - 'A' + 1] = true;
			}
		}
	}
//	for (int i = 1; i <= 26; i ++) {
//		cout << flag[i] << endl;
//	}
	int now = 1;
	for (int i = 1; i <= 32; i ++) {
		if (i <= 3) {
			cout << "*";
			continue ; 
		}
		if (i >= 30) {
			cout << "*";
			continue ;
		}
		if (flag[now]) {
			cout << zm[now];
		} else {
			cout << "*";
		}
		now ++;
		if (i % 8 == 0) {
			cout << endl;
		}
	}
	return 0;
}

赛时:100point

赛后:无

T2

题目其实就是让我们先对客人价格进行排序。

看一下

\(max_{i=1}^{i<=n}\)

\(定a_i作为单价让后n-i个人付得起钱\)

贴一下代码
#include <bits/stdc++.h>
using namespace std;
#define fre(c) freopen(c".in","r",stdin);freopen(c".out","w",stdout);
#define ll long long
#define endl "\n"
#define ios ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define cst const
cst int N = 2 * 1e5 + 5;
ll n, a[N], ans, now;
ll read() {
	char c;
	ll sum = 0;
	int f = 1;
	c = getchar();
	while (!isdigit(c)) {
		if (c == '-')
			f *= -1;
		c = getchar();
	}
	while (isdigit(c)) {
		sum = sum * 10 + (c - '0');
		c = getchar();
	}
	return sum * f;
}
int main() {
	ios
//	fre("1")
	n = read();
	for (ll i = 1; i <= n; i ++) {
		a[i] = read();
	}
//	for (ll i = 1; i <= n; i ++) {
//		cout << a[i] << endl;
//	}
	sort(a + 1, a + 1 + n);
	for (ll i = 1; i <= n; i ++) {
		now = a[i] * (n - i + 1);
		ans = max(ans, now);
	}
	cout << ans;
	return 0;
}

赛时:100point

赛后:无

T3

模拟,不难发现对于每次扩展,只是在右下角扩展出一个不同的,而其他地方保持不变

可以得到以下思路
int dx = 2 * i;//i为当前扩展的行
int dy = 2 * j;//j为当前扩展的列
//扩展
cnt[dx][dy] = cnt[dx][dy + 1] = cnt[dx + 1][dy] = pos;//pos为cnt[i][j]的数值
cnt[dx + 1][dy + 1] = (pos == '0') ? '1' : '0';
//cnt为当前扩展后的答案

在这里我建议直接用vector<string> ans(1, string(1, ('0' + val)));,这样可以直接取size做大小

贴一下代码
#include <bits/stdc++.h>
using namespace std;
#define fre(c) freopen(c".in","r",stdin);freopen(c".out","w",stdout);
#define ll long long
#define endl "\n"
#define ios ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define cst const
cst int N = 2048 + 5;
string s[N];
int n, val;
ll read() {
	char c;
	ll sum = 0;
	int f = 1;
	c = getchar();
	while (!isdigit(c)) {
		if (c == '-')
			f *= -1;
		c = getchar();
	}
	while (isdigit(c)) {
		sum = sum * 10 + (c - '0');
		c = getchar();
	}
	return sum * f;
}
int main() {
	ios
//	fre("")
	cin >> n >> val;
	if (n == 0) {
		cout << val;
		return 0;
	}
	vector<string> ans(1, string(1, ('0' + val)));//当一回sb,主要是size太好用了
//	cout << ans[0][0];
	for (int k = 1; k <= n; k ++) {
		int x = ans.size();
		int y = ans[0].size();
		vector<string> cnt(2 * x, string(2 * y, '0'));
		for (int i = 0; i < x; i ++) {
			for (int j = 0; j < y; j ++) {
				char pos = ans[i][j];
				int dx = 2 * i;
				int dy = 2 * j;
				cnt[dx][dy] = cnt[dx][dy + 1] = cnt[dx + 1][dy] = pos;
				cnt[dx + 1][dy + 1] = (pos == '0') ? '1' : '0';
			}
		}
		ans = cnt;
	}
	for (int i = 0; i < ans.size(); i ++) {
		for (int j = 0; j < ans[0].size(); j ++) {
			cout << ans[i][j];
		}
		cout << endl;
	}
	return 0;
}
/*
其实每次扩展就是在一个4*4平面的右下角扩展一个不一样的
*/

赛时:100point

赛后:无

T4

其实不难看出是一道图论题目,链式前向星建好边后只需要bfs全部前置技巧即可

贴一下代码
#include<bits/stdc++.h>
using namespace std;
#define fre(c) freopen(c".in","r",stdin);freopen(c".out","w",stdout);
#define ll long long
#define endl "\n"
#define ios ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define cst const
cst int maxn=2 * 1e5 + 5;
struct Edge {
	int to;
	int next;
} edge[maxn];
int head[maxn];
ll t[maxn];
queue<int >q;
bool vis[maxn];
int tot=0;
void link(int u,int v) {
	edge[tot].to=v;
	edge[tot].next=head[u];
	head[u]=tot ++;
}
int main() {
	memset(head,-1,sizeof(head));
	memset(vis,false,sizeof(vis));
	int n;
	cin >> n;
	for(int i = 1; i <= n; i ++) {
		int k;
		cin >> t[i] >> k;
		for(int j = 0; j < k; j ++) {
			int a;
			cin >> a;
			link(i,a);
		}
	}
	ll to = 0;
	q.push(n);
	vis[n] = true;
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		to += t[u];
		for(int i = head[u]; i!=-1; i=edge[i].next) {
			int v=edge[i].to;
			if(!vis[v]) {
				vis[v]=true;
				q.push(v);
			}
		}
	}
	cout<<to;
	return 0;
}

赛时:12point

赛后:100point

T5

先补充一个知识点:

回文序列的性质:对于一个回文序列,对称位置的元素必须相同。即对于位置i和位置n-i+1的元素必须相同。

我们可以使用并查集来管理需要合并的馅料编号。对于每一对对称位置的馅料编号,如果它们不同,我们需要将它们合并到同一个集合中。合并操作代表了我们需要将这些馅料统一成同一个编号。

每次合并两个不同的馅料编号集合时,相当于进行了一次替换操作。因此,最少操作次数等于需要合并的不同馅料对数。

  • 初始化并查集:为每个馅料编号初始化一个独立的集合。

  • 处理对称位置:遍历序列的前半部分,对于每个位置i,检查\(a_i\)\(a_{n-i+1}\)是否相同:

    • 如果不同,使用并查集合并这两个馅料编号所在的集合。
  • 统计操作次数:遍历所有馅料编号,统计每个集合的代表元素。操作次数等于不同集合的数量减去1(因为最终所有需要合并的馅料都会属于同一个集合)。

贴一下标程
#include<bits/stdc++.h>
using namespace std;
#define fre(c) freopen(c".in","r",stdin);freopen(c".out","w",stdout);
#define ll long long
#define endl "\n"
#define ios ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define cst const
cst int N = 2 * 1e5 + 5;
map<int,map<int,int> > mp;
int n,a[N],sum[N],f[N],ans;
int find(int x){
	return x!=f[x]?f[x]=find(f[x]):x;
}
int main(){
	ios
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> a[i];
		f[a[i]]=a[i];
		sum[a[i]]=1;
	}
	for(int i=1;i<=n/2;i++){
		if(find(a[i])!=find(a[n-i+1])){
			a[n-i+1]=find(a[n-i+1]);
			a[i]=find(a[i]);
			sum[a[i]]+=sum[a[n-i+1]];
			sum[a[n-i+1]]=0;
			f[a[n-i+1]]=a[i];
		}
	}
	for(int i=1;i<=n;i++){
		ans+=sum[find(a[i])]-1;
		sum[find(a[i])]=1;
	}
	cout << ans;
	return 0;
}

赛时:6point

赛后:100point

posted @ 2025-08-06 15:58  Kevinrzy103874  阅读(18)  评论(0)    收藏  举报