Kevinrzy103874的博客

Kevinrzy103874的博客

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

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

模拟赛SXJ202507250900比赛记录&题解

题目请看

T1

一点点贪心,因为包包每天都要吃饺子,所以问题可以转化为看是之前\(买饺子的钱+存储的钱\)\(现在购买饺子的钱\),把它们进行比较,就能知道怎样更划算了;

贴一下代码
#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 ll N = 1e5 + 5;
ll n, c, a[N], ans, daymi;
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")
	fre("dumpling")
	n = read();
	c = read();
	for (ll i = 1; i <= n; i ++) {
		a[i] = read();
	}
	daymi = a[1];
	for (ll i = 1; i <= n; i ++) {
		daymi = min(daymi, a[i] - c * i);
		ans += daymi + c * i;
	}
	cout << ans;
	return 0;
}

赛时:100point

赛后:无

T2

总感觉在AtCoder见过

其实可以用一个临时变量存储当前度数,每次输入加在这个变量上,当它超过一个圆(\(360度\))时,对它\(\%360\)就可以啦!再用一个桶数组存储是否出现,之后枚举\(0->360\) 坑点,算最大距离。

赛时,因忘记首刀同时切在\(0度\)\(360度\)上,忘记prefix[360] ++了,痛失

12point

贴一下代码
#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 ll N = 360 + 5;
ll n, a[N], x, prefix[N], jd = 0, ma = -0x3f3f3f3f, last = -1;
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("2");
	fre("pizza")
	n = read();
	for (ll i = 1; i <= n; i ++) {
		x = read();
		jd += x;
		jd %= 360;
		a[i] = jd;
		prefix[a[i]] ++;
	}
	prefix[0] ++;
	prefix[360] ++;
	for (int i = 0; i <= 360; i ++) {
		if (prefix[i] >= 1 && last != -1) {
			ma = max(ma, i - last);
			last = i;
		}
		if (prefix[i] >= 1) {
			last = i;
		}
	}
	cout << ma;
	return 0;
}

赛时:88point

赛后:100point

T3

看似很复杂的一道问题,实则我们只需要专心用\(O(n)\)的复杂度来统计相同颜色的长度,并在颜色变化时记录:

  • 计算能在当前连续块中进行的最大有效操作数
  • 每个有效操作可以增加2个记忆碎片
  • 更新剩余操作次数
  • 处理特殊情况(\(k \neq 2\)且连续块长度为偶数时,连续区间加\(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 ll N = 1e5 + 5;
cst ll INF = 0x3f3f3f3f;
ll t;
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;
}
void fun() {
	ll n, m, k, cnt = 0, ans = 0, sum = 0, tmp = 0;
	n = read();
	m = read();
	k = read();
	vector<ll> a(n + 2);//懒得memset
	for (ll i = 1; i <= n + 1; i ++) {
		if (i <= n) {
			cin >> a[i];
		} else {
			a[i] = k + 1;	
		}
		if (a[i] == a[i - 1] || i == 1) {
			sum++;	
		} else {
			ans ++;
			tmp = m > (sum - 1) / 2 ? (sum - 1) / 2 : m;
			ans += tmp * 2;
			m -= tmp;
			if(k != 2 && !(sum & 1)) {
				cnt ++;
			}
			sum = 1;
		}
	}
	cout << ans + min(m, cnt) << endl;
}
int main() {
	fre("art")
	t = read();
	while(t --) {
		fun();
	}
	return 0;
}

赛时:30point

赛后:100point

T4

很版的一道\(二维dp\)题,每当包包遇到一个食物是,可以判断一下:

\( \left\{ \begin{aligned} &op = 毒食:只能选择吃解毒食物或者不吃 \\ &op = 解毒食:能选择吃或者不吃 \end{aligned} \right. \)

\(op=1\):代表毒食

\(op=0\):代表解毒食

得到以下状态转移方程:

(\(i\)代表从\(1\)\(n\)的每一种食物,\(tmp\)表示每种食物的美味度)

\( \left\{ \begin{aligned} &op = 1:f[i][1]=max(f[i][1],f[i-1][0]+tmp)\\ &op = 0:f[i][0]=max(f[i][0],max(f[i-1][0],f[i-1][1])+tmp) \end{aligned} \right. \)

可得以下代码:

贴一下代码
#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 ll N = 3 * 1e5 + 5;
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;
}
ll n, op, tmp, f[N][5];
int main() {
	fre("taste")
	n = read();
	for(int i = 1; i <= n; i ++) {
		op = read();
		tmp = read();
		f[i][0] = f[i - 1][0];
		f[i][1] = f[i - 1][1];
		if(op) {
			f[i][1] = max(f[i][1], f[i - 1][0] + tmp);	
		} else {
			f[i][0] = max(f[i][0], max(f[i - 1][0], f[i - 1][1]) + tmp);	
		}
	}
	cout << max(f[n][0],f[n][1]);
	return 0;
}

赛时:17point(没时间打,只打了个表)

赛后:100point

T5

其实题目意思还是挺明显

就是要我们把每一道工序看成一个顶点,每道工序看成一条边。

我们来分析样例&1,根据关系可知以下图:

graph TD 1 --- 2 1 --- 3 2 --- 3 2 --- 4 3 --- 4

\(4\)相连的有\(2\)个点。

我们可以用邻接表或链式前向星存图,再\(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 N = 2 * 1e5 + 5;
cst int mod = 1e9 + 7;
queue<int> que;
map<int, int > stp;
int n, m, k, t, op;
int sum;
int ans, tmp, pre, cnt, tot, pos;
ll a[N], f[N];
int head[N], vis[N];
struct edge {
	int to, nxt;
} e[N*2];
void add(int x, int y) {
	e[++tot] = {y, head[x]};
	head[x] = tot;
}
int main() {
	// freopen("1.txt", "r", stdin);
	freopen("Alchemy.in", "r", stdin);
	freopen("Alchemy.out", "w", stdout);
	cin >> n >> m;
	for(int i = 1, u, v; i <= m; i++) {
		scanf("%d%d", &u, &v);
		add(u, v);
		add(v, u);
	}
	que.push(1); 
	f[1] = 1;
	stp[1] = 0;
	while (!que.empty()) {
		tmp = que.front();
		vis[tmp] = 2;
		que.pop();
		for (int i = head[tmp]; i; i = e[i].nxt) {
			pos = e[i].to;
			if (! stp[pos]) 
				stp[pos] = stp[tmp] + 1;
			if (vis[pos] != 2 && stp[pos] >= stp[tmp] + 1) {
				f[pos] = (f[pos] + f[tmp]) % mod;
				if (! vis[pos]) {
					vis[pos] = 1;
					que.push(pos);
				}
			} 
		}
	}
	cout << f[n];
	return 0;
}

赛时:6point(没时间打,只打了个表)

赛后:100point

posted @ 2025-07-25 16:37  Kevinrzy103874  阅读(42)  评论(0)    收藏  举报