首页 > 编程语言 >2024 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛)

2024 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛)

时间:2024-08-05 22:09:15浏览次数:18  
标签:return CAIP int auto cin 国赛 2024 && dis

2024 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛)

前言

补题只补了前四道,第五题打个暴力都有 \(24\) 分,我这死活只有 \(22\) 分 \(QAQ\)

RC-u1 大家一起查作弊

思路

按题意模拟。

不过很奇怪赛时用 getline 老是读入不了,还好换成 cin 直接读也问题不大。

代码

#include <bits/stdc++.h>

using namespace std;

int  main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto check0 = [](char c)->bool{
		bool res = 0;
		if (c >= '0' && c <= '9') res = 1;
		if (c >= 'a' && c <= 'z') res = 1;
		if (c >= 'A' && c <= 'Z') res = 1;
		return res;
	};

	auto check1 = [](string s)->int{
		int res = 0;
		for (int i = 0; i < s.size(); i ++) {
			if (s[i] >= '0' && s[i] <= '9')
				res ++;
		}
		return res;
	};

	auto check2 = [](string s)->int{
		int res = 0;
		for (int i = 0; i < s.size(); i ++) {
			if (s[i] >= 'a' && s[i] <= 'z')
				res ++;
		}
		return res;
	};

	auto check3 = [](string s)->int{
		int res = 0;
		for (int i = 0; i < s.size(); i ++) {
			if (s[i] >= 'A' && s[i] <= 'Z')
				res ++;
		}
		return res;
	};

	vector<string> a;
	string s;
	while (cin >> s) {
		for (int i = 0; i < s.size(); i ++) {
			if (check0(s[i])) {
				int j = i + 1;
				while (j < s.size() && check0(s[j])) {
					j ++;
				}
				a.emplace_back(s.substr(i, j - i));
				i = j;
			}
		}
	}

	int ans1 = 0, ans2 = 0;
	for (auto s : a) {
		ans2 += s.size();
		int x = check1(s), y = check2(s), z = check3(s);
		if (x && y && z) ans1 += 5;
		else if (x && (y || z)) ans1 += 3;
		else if (y && z) ans1 += 1;
	}

	cout << ans1 << '\n' << ans2 << ' ' << a.size() << '\n';

	return 0;
}

RC-u2 谁进线下了?II

思路

按题意模拟,注意不要输出未参赛的队伍分数。

代码

#include <bits/stdc++.h>

using namespace std;

int  main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto get = [](int x)->int{
		if (x == 1) return 25;
		if (x == 2) return 21;
		if (x == 3) return 18;
		return 20 - x;
	};

	int n;
	cin >> n;

	vector<array<int, 2>> a(31);

	for (int i = 1; i <= 30; i ++) {
		a[i][1] = i;
	}

	set<int> ok;
	while (n--) {
		for (int i = 1; i <= 20; i ++) {
			int c, p;
			cin >> c >> p;
			a[c][0] += get(p);
			ok.insert(c);
		}
	}

	sort(a.begin() + 1, a.end(), [](auto x, auto y) {
		if (x[0] == y[0]) return x[1] < y[1];
		return x[0] > y[0];
	});

	for (int i = 1; i <= 30; i ++) {
		if (ok.count(a[i][1])) {
			cout << a[i][1] << ' ' << a[i][0] << '\n';
		}
	}

	return 0;
}

RC-u3 势均力敌

思路

赛后听佬们说有规律,不过我是蠢比找不出规律,只好写暴力了 \(\dots\)

考虑到 \(4!=24\),直接暴力搜索有 \(2^{24}\) 会超时,那就双向搜索好了,要找两个集合,使其平方和相等, 枚举一半 \(2^{12}\) 找到两个集合各一半的和假设为 \([a,b]\),再枚举另一半找到的和假设为 \([c,d]\),那么有 \(a+c=b+d\),即 \(a-b=c-d\),所以我们只要存下差值即可,然后还要存下两个集合中选的数有没有一半,这里我是直接判断状态中 \(1\) 的个数有没有一半,找到了就直接输出。

代码

#include <bits/stdc++.h>

using i64 = long long;

using namespace std;

int  main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n;
	cin >> n;

	vector<int> a(n + 1);
	for (int i = 1; i <= n; i ++)
		cin >> a[i];

	vector<int> num;
	int vis[5] {};
	auto dfs = [&](auto & self, int x, int res)->void{
		if (x == n) {
			num.emplace_back(res);
			return ;
		}

		for (int i = 1; i <= n; i ++) {
			if (!vis[i]) {
				vis[i] = 1;
				self(self, x + 1, res * 10 + a[i]);
				vis[i] = 0;
			}
		}
	};

	dfs(dfs, 0, 0);

	int y = 1;
	for (int i = 1; i <= n; i ++)
		y *= i;

	y /= 2;

	auto print = [&](int a, int b)->void{
		for (int i = 0; i < y; i ++) {
			if (a >> i & 1) {
				cout << num[i] << '\n';
			}
		}
		for (int i = 0; i < y; i ++) {
			if (b >> i & 1) {
				cout << num[i + y] << '\n';
			}
		}
	};

	map<i64, vector<int>> mp;
	for (int i = 1; i < (1 << y); i ++) {
		i64 f = 0, res1 = 0, res0 = 0;
		for (int j = 0; j < y; j ++) {
			if (i >> j & 1) {
				res1 += num[j] * num[j];
			} else {
				res0 += num[j] * num[j];
			}
		}
		mp[res1 - res0].push_back(i);
	}

	for (int i = 1; i < (1 << y); i ++) {
		i64 f = 0, res1 = 0, res0 = 0;
		for (int j = 0; j < y; j ++) {
			if (i >> j & 1) {
				res1 += num[j + y] * num[j + y];
			} else {
				res0 += num[j + y] * num[j + y];
			}
		}
		if (mp.count(res0 - res1)) {
			for (auto st : mp[res0 - res1]) {
				if (__builtin_popcount(i) + __builtin_popcount(st) == y) {
					print(st, i);
					return 0;
				}
			}
		}
	}

	return 0;
}

RC-u4 City 不 City

思路

赛中只拿了 20 分,后来没时间 debug 了,赛后来改了几行就过了 \(\dots\)

很一眼的 \(dijkstra\),但是需要维护路径上的最高热度值,所以添加一个 \(path\) 数组维护路径上除起点和终点以外的最大热度值最小即可。

代码

#include <bits/stdc++.h>

using i64 = long long;

using namespace std;

int  main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n, m, s, t;
	cin >> n >> m >> s >> t;

	vector<int> a(n + 1);
	for (int i = 1; i <= n; i ++) {
		cin >> a[i];
	}

	vector<vector<pair<int, int>>> g(n + 1);
	for (int i = 0; i < m; i ++) {
		int u, v, w;
		cin >> u >> v >> w;
		g[u].push_back({v, w});
		g[v].push_back({u, w});
	}

	vector<int> dis(n + 1, 1e9), path(n + 1);
	priority_queue<array<int, 2>> Q;

	dis[s] = 0;
	Q.push({0, s});
	while (Q.size()) {
		auto [d, u] = Q.top();
		Q.pop();


		if (dis[u] < d) continue;

		for (auto [v, w] : g[u]) {
			if (dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				Q.push({ -dis[v], v});
				if (v != t) {
					path[v] = max(path[u], a[v]);
				} else {
					path[v] = path[u];
				}
			} else if (dis[v] == dis[u] + w) {
				path[v] = min(max(a[v], path[u]), path[v]);
			}
		}
	}

	if (dis[t] == 1e9) {
		cout << "Impossible\n";
	} else {
		cout << dis[t] << ' ' << path[t] << '\n';
	}

	return 0;
}

RC-u5 贪心消消乐

思路

唉不太会,听别人说写个二维前缀和暴力都能有 \(24\) 分来着,我后来改了好久也只会 \(22\) 分的,等之后改完了再重新更新下吧。

大概思路就是, \(n^3\) 的前缀和扫描每行的最大子段和 \(dp\),会 wa 第二个和最后一个点,想不明白。

哦对了,这个傻逼题还把行和列反着给,一个样例给我硬控几分钟,wok。

代码

#include <bits/stdc++.h>

using i64 = long long;

using namespace std;

int  main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n;
	cin >> n;

	const int inf = -5e5;

	vector a(n + 1, vector<int>(n + 1));
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n; j ++) {
			cin >> a[j][i];
			if (!a[j][i])
				a[j][i] = inf;
		}
	}

	auto Min = [](array<int, 5> &x, array<int, 5> &y)->array<int, 5> {
		if (x[0] != y[0])
			return x[0] > y[0] ? x : y;
		if (x[1] != y[1])
			return x[1] < y[1] ? x : y;
		if (x[2] != y[2])
			return x[2] < y[2] ? x : y;
		if (x[3] != y[3])
			return x[3] < y[3] ? x : y;
		return x[4] < y[4] ? x : y;
	};

	int ans = 0;
	while (true) {
		// for (int i = 1; i <= n; i ++)
		// 	for (int j = 1; j <= n; j ++)
		// 		cout << a[i][j] << " \n"[j == n];
		array<int, 5> res{inf, 0, 0, 0, 0};
		for (int i = 1; i <= n; i ++) {
			vector<int> pre(n + 1);
			for (int j = i; j <= n; j ++) {
				vector<array<int, 2>> dp(n + 1);
				// cout << i << ' ' << j << ":\n";
				for (int k = 1; k <= n; k ++) {
					pre[k] += a[j][k];
					// cout << pre[k] << " \n"[k == n];
				}
				for (int k = 1; k <= n; k ++) {
					dp[k][1] = k;
					if (k > 1 && dp[k - 1][0] + pre[k] > dp[k][0]) {
						dp[k] = dp[k - 1];
					}
					dp[k][0] += pre[k];
					array<int, 5> t = {dp[k][0], i, dp[k][1], j, k};
					res = Min(res, t);
				}
			}
		}

		if (res[0] <= 0) {
			break;
		}

		ans += res[0];
		auto [v, x1, y1, x2, y2] = res;
		cout << '(' << x1 << ", " << y1 << ") (" << x2 << ", " << y2 << ") " << v << '\n';

		int len = y2 - y1 + 1, no = -1e5;
		for (int i = x1; i <= x2; i ++) {
			for (int j = y1; j <= y2; j ++) {
				a[i][j] = no;
			}
			for (int j = n; j >= 1; j --) {
				if (a[i][j] != no) {
					int k = j;
					while (k + 1 <= n && a[i][k + 1] == no) {
						swap(a[i][k], a[i][k + 1]);
						k ++;
					}
				}
			}
			for (int j = 1; j <= n; j ++) {
				if (!a[i][j]) {
					a[i][j] = inf;
				}
			}
		}
	}

	cout << ans << '\n';

	return 0;
}

标签:return,CAIP,int,auto,cin,国赛,2024,&&,dis
From: https://www.cnblogs.com/Kescholar/p/18344130

相关文章

  • 2024上岸|314数农备考攻略
    前言......
  • 2024上岸|鱼类增养殖学(927)129备考攻略
    前言......
  • CEOI2024
    Day1T1海战不难发现,如果两艘船会相遇,那么他们之间必然要满足某些要求。首先同向的之间必然不会相遇,然后就可以分\(6\)种情况讨论。(下文中认为\((x_1,y_1)\)为与前的一项,\((x_2,y_2)\)为与后的一项)。N与S:要求\(x_1=x_2\)且\(y_2<y_1\),相遇时间为\(\dfrac{1}{2}(y_1......
  • [20240804]关于kitty设置与linux LANG环境设置问题.txt
    [20240804]关于kitty设置与linuxLANG环境设置问题.txt--//更正我以前理解的一个混沌的地方:--//我以前个人的工作习惯:LANG=en_US,kittyRemotecharacterset选择Usefontencoding.--//目前这样的设置存在一些问题:--//kitty设置LANG=en_US.UTF-8的情况下,kittywindow->Trans......
  • 2024 年 8 月错题集
    CF1887CMinimumArray题目链接:https://codeforces.com/problemset/problem/1887/C题意:给定一个长度为\(n\)的整数序列,共\(q\)此操作,每次操作会将序列的一段区间同时加上某个数,求出所有操作产生的新序列中字典序最小的一个。思路:由区间加想到差分,要求序列字典序最小及要......
  • 【笔记】非传统题选讲 2024.8.5
    今天睡着了。发了只是为了完整性。[CF1672E]notepad.exe先二分得到总长度\(\suml_i+n-1\)记为\(w_1\),然后考虑其它行数\(h\),最优的情况只能是每一行都用换行顶替一个空格,此时面积为\(w_h\cdoth=w_1-h+1\),所以\(w_h=\left\lfloorw_1/h\right\rfloor\)为唯一可能更新答......
  • 【京东云新品发布月刊】2024年7月产品动态
    京东云7月产品动态:1.【消息队列RocketMQ】新品上线消息队列RocketMQ是京东云基于ApacheRocketMQ打造的一款低延迟、高并发、高可用、高可靠的分布式消息队列服务。支持开源客户端零改造接入,同时具备计算存储分离,灵活扩缩容的优势。能够轻松处理百万级TPS的吞吐量,适用于各类大......
  • 【日常开发】一个list集合 根据a字段 b字段进行分组 并计算c字段的和 并封装这种格式:
    ......
  • 牛客多校2024-6
    A-Cake(神金,害我调了一个半小时)Alice和Bob玩一个游戏。游戏分为2阶段。阶段1:有一棵边权值为\(0\)或\(1\)的有根树,两人轮流走,Alice先走,走到叶子就停下来。记录下经过边的权值形成一个字符串\(S\)阶段2:Bob将一个蛋糕切成\(len(S)\)块,块可以为空。然后遍历\(S\)的......
  • 学习笔记 韩顺平 零基础30天学会Java(2024.8.5)
    P460八大Wrapper类     黄色的父类是number,黑色的是自己独立的P461装箱和拆箱     手动装箱示例:                             intn1=100;                Intergerinterger=newInterger(n1);//......