比赛链接:

https://vjudge.csgrandeur.cn/contest/160686

A - Cooking Competition

题目大意:

\(Kobayashi\)\(Tohru\) 比赛,比 \(n\) 轮,输入 \(n\) 个数,如果是 1,该轮 \(Kobayashi\) + 1 分,如果是 2 \(Tohru\) + 1 分,如果是 3 两个人都 + 1,如果是 4,两个人都 -1。判断谁最后获胜,若平局,输出 \(Draw\)

思路:

按题意模拟。

代码:

#include <bits/stdc++.h>
using namespace std;
int n, a, T = 1;
void solve(){
	cin >> n;
	int p = 0, q = 0;
	for (int i = 1; i <= n; i ++ ){
		cin >> a;
		if (a == 1) p++;
		else if (a == 2) q++;
	}
	if (p > q) cout << "Kobayashi\n";
	else if (p < q) cout << "Tohru\n";
	else cout << "Draw\n";
}
int main(){
	cin >> T;
	while (T--)
		solve();
	return 0;
}

B - Problem Preparation

题目大意:

省赛要出题,现在出题人出了 \(n\) 道题,每道题的难度为 \(a_i\),这套题要满足一下四个条件。
1、题目的数量要在 10 道到 13 道左右。
2、最简单的一道题的难度要为 1
3、难度为 1 的题目至少有两道
4、除了最难的一道题,任意两道题之间的难度差距不超过 2

思路:

\(a\) 数组排序,然后依次是否符合条件即可。

代码:

#include <bits/stdc++.h>
using namespace std;
int T = 1, n;
void solve(){
	cin >> n;
	vector <int> a(n);
	for (int i = 0; i < n; i ++ )
		cin >> a[i];
	sort(a.begin(), a.end());
	if (n < 10 || n > 13 || a[0] != 1 || a[1] != 1) cout << "No\n";
	else{
		for(int i = 2; i < n - 1; i ++ )
			if (a[i - 1] + 2 < a[i]){
				cout << "No\n";
				return;
			}
		cout << "Yes\n";
	}
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> T;
	while (T--)
		solve();
	return 0;
}

C - What Kind of Friends Are You?

题目大意:

动物园里面有 \(c\) 个动物,现在要去分辨其中 \(n\) 种动物分别是什么动物,问每个动物相同的 \(q\) 个问题,每个问题由 \(m\) 个动物集合组成,若动物回答 \(yes\),说明它是其中的一个动物,若回答 \(no\),说明它不在这个集合中,接下来有一个 \(n * q\) 的矩阵,若为 0,表示动物回答的是 \(no\),若为 1,则表示 \(yes\)。判断每个动物分别是什么。

思路:

看到问题的数据范围是小于 21 的,可以想到二进制,将每个动物以二进制的方式表示,若动物存在这个问题的集合中,则它的值加上该问题对应的二进制值。
问问题的时候找等于该值的动物的数量,若为 1,说明就是该动物,若不为 1,则说明判断不了。
\(ps\):这道题太多 \(for\) 循环会 \(T\)

代码:

#include <bits/stdc++.h>
using namespace std;
int T = 1, n, q, c, m, a;
void solve(){
	cin >> n >> q >> c;
	vector <string> name(c);
	map <string, int> cnt;
	for (int i = 0; i < c; i ++ )
		cin >> name[i];
	for (int i = 0; i < q; i ++ ){
		cin >> m;
		for (int j = 0; j < m; j ++ ){
			string s;
			cin >> s;
			cnt[s] += (int)pow(2, i);
		}
	}
	for (int i = 0; i < n; i ++ ){
		int k = 0, num = 0;
		string ans = "";
		for (int j = 0; j < q; j ++ ){
			cin >> a;
			k += a * (int)pow(2, j);
		}
		for (auto x : name)
			if (cnt[x] == k){
				num++;
				ans = x;
			}
		if (num == 1) cout << ans << "\n";
		else cout << "Let's go to the library!!\n";
	}
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin >> T;
	while (T--)
		solve();
	return 0;
}

D - Let's Chat

题目大意:

若两个人连续互相发消息 \(m\) 天,那么亲密度就会 + 1。现在已知 \(n\) 天两个人互发消息的记录,问两人的亲密度会增加多少。
输入 \(x\)\(y\)。接下来 \(x\) 行每行两个数,\(l\)\(r\),表示在 \(l\)\(r\) 天中 \(a\) 都给 \(b\) 发了消息,后面 \(y\) 行表示在 \(l\)\(r\) 天中 \(b\)\(a\) 发了消息。

思路:

暴力枚举每一个区间进行匹配,重复的那几天就是两人互发消息的时间,两人连续互发发消息的天数 - \(m\) + 1 就是亲密度的增加值。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int T = 1, n, m, x, y;
struct node{
	int l, r;
}a[N], b[N];
void solve(){
	cin >> n >> m >> x >> y;
	for (int i = 0; i < x; i ++ )
		cin >> a[i].l >> a[i].r;
	for (int i = 0; i < y; i ++ )
		cin >> b[i].l >> b[i].r;
	int ans = 0;
	for (int i = 0; i < x; i ++ )
		for (int j = 0; j < y; j ++ ){
			int p = max(a[i].l, b[j].l), q = min(a[i].r, b[j].r);
			if(q - p + 1 >= m)
				ans += q - p - m + 2;
		}
	cout << ans << "\n";
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	cin >> T;
	while (T --)
		solve();
	return 0;
}

E - Seven Segment Display

题意:

有一个八位的七段显示器,现在显示的是 \(s\),问从 \(s\) 开始(包括 \(s\))的 \(n\) 个显示所要耗费的能量为多少。
下图为每个字符对应的能量。

显示字符从 "00000000" 开始,到 "FFFFFFFF" 截止,十六进制,显示的顺序是循环的,"FFFFFFFF" 的下一位就是 "00000000"。

思路:

分两种情况,一种是超过了 "FFFFFFFF" 之后发生循环的情况,一种没有超过。
接着就是简单的数位 \(dp\) 的过程。
注意:
1.每次计算的时候要将整个数字数组清空,前面有可能就不是 0,导致计算结果错误。
2.数字的长度为 8,短了就会导致前面的 0 少计算了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
map <char, LL> mp;
LL cost[] = {6,2,5,5,4,5,6,3,7,6,6,5,4,5,5,4}, INF;
LL dp[10][150], dig[10];
LL get(string s){
	LL ans = 0;
	for (int i = 0; i < 8; i ++ )
		ans = ans * 16 + mp[s[i]];
	return ans;
}
LL dfs(LL pos, LL sum, LL limit){
	LL ans = 0;
	if (pos == 0) return sum;
	if (!limit && dp[pos][sum] != -1) return dp[pos][sum];
	LL up = (limit ? dig[pos] : 15);
	for (int i = 0; i <= up; i ++ )
		ans += dfs(pos - 1, sum + cost[i], limit && (i == up) );
	if (!limit) dp[pos][sum] = ans;
	return ans;
}
LL cal(LL x){
	LL len = 0;
	memset(dig, 0, sizeof dig);
	while(x){
		dig[ ++ len] = x % 16;
		x /= 16;
	}
	return dfs(8, 0, 1);
}
void solve(){
	LL n;
	string s;
	cin >> n >> s;
	LL x = get(s), y = x + n - 1;
	if (y <= INF) cout << cal(y) - cal(x - 1) << "\n";
	else cout << cal(INF) - cal(x - 1) + cal(y - 1 - INF) << "\n";
}
void init(){
	memset(dp, -1, sizeof dp);
	for (char i = '0'; i <= '9'; i ++ )
		mp[i] = i - '0';
	for (char i = 'A'; i <= 'F'; i ++ )
		mp[i] = i - 'A' + 10;
	INF = get("FFFFFFFF");
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	init();
	LL T;
	cin >> T;
	while(T -- )
		solve();
	return 0;
}
posted on 2022-04-07 22:42  Hamine  阅读(334)  评论(0编辑  收藏  举报