ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

"蔚来杯"2022牛客暑期多校训练营10

2022-08-26 13:32:35  阅读:158  来源: 互联网

标签:10 qp int 蔚来 LL 多校 cin ans


比赛链接:

https://ac.nowcoder.com/acm/contest/33195

F.Shannon Switching Game?

题意:

给定一个无向图,初始有一张纸牌在点 \(s\),两个玩家 \(Join Player\) 和 \(Cut Palyer\) 轮流行动,\(Cut Palyer\) 先动。
\(Cut Palyer\) 每次可以移除一条和纸牌所在点相邻的边,\(Join Player\) 每次可以让纸牌沿着当前点的一条未删除的边移动。
如果纸牌某时刻被移动到 \(t\) 则 \(Join Player\) 获胜,否则 \(Cut Palyer\) 获胜,问双方均采用最优策略的情况下,谁会获胜。

思路:

从终点出发来考虑,将满足条件的点作为一个集合,某个点要有两条能到达集合的点中的路径才能够到达这个终点所包含的集合,因为 \(Cut Player\) 删掉一条边之后,还能够过来,按照这个思路进行一个 \(bfs\) 就行。

题意:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
void solve(){
	LL n, m, s, t;
	cin >> n >> m >> s >> t;
	vector < vector<LL> > e(n + 1);
	for (int i = 0; i < m; i ++ ){
		LL u, v;
		cin >> u >> v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	auto bfs = [&](){
		vector <LL> deg(n + 1), used(n + 1);
		used[t] = 1;
		queue <LL> q;
		q.push(t);
		while(q.size()){
			LL u = q.front();
			q.pop();
			for (auto v : e[u]){
				if (used[v]) continue;
				deg[v] ++ ;
				if (deg[v] >= 2){
					used[v] = 1;
					q.push(v);
				}
			}
		}
		if (used[s]) cout << "Join Player\n";
		else cout << "Cut Player\n";
	};
	bfs();
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	LL T = 1;
	cin >> T;
	while(T -- ){
		solve();
	}
	return 0;
}

H.Wheel of Fortune

题意:

两个人玩炉石,两个人的血量分别为 \(A\) 和 \(B\),每人有七个兵,血量分别为 \(a_i\) 和 \(b_i(1 <= i <= 7)\),每回合随机选择一个单位扣 10 点血,问 \(A\) 获胜的概率,答案对 998244353 取模。

思路:

因为只角色死亡才会结束游戏,所以兵的血量其实没有影响。先计算出每个人可以承受多少次伤害,即 \(\lceil \frac{A}{10} \rceil\) 和 \(\lceil \frac{B}{10} \rceil\),分别记为 \(a\) 和 \(b\)。
接下来就枚举每一种可能,\(A\) 最多能承受 \(a - 1\) 次伤害(因为要赢,所以还要有血)。
承受 0 次伤害,答案就是 \(\frac{1}{2^b}\)。
承受 1 次伤害,只要在 \(b\) 死之前受一次伤害就行,考虑插空法,这一次伤害有 \(C_{b}^{1}\) 种可能,答案就是 \(C_{b}^{1} \frac{1}{2^{b + 1}}\)。
承受 2 次伤害,\(C_{b + 1}^{2} \frac{1}{2^{b + 2}}\)
...
通过递推求解就行。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int P = 998244353;
LL qp(LL a, LL k, LL p){
	LL ans = 1;
	while (k){
		if (k & 1) ans = ans * a % p;
		k >>= 1;
		a = a * a % p;
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	LL A, B, t;
	cin >> A;
	for (int i = 1; i <= 7; i ++ )
		cin >> t;
	cin >> B;
	for (int i = 1; i <= 7; i ++ )
		cin >> t;
	LL a = (A + 9) / 10, b = (B + 9) / 10;
	LL x = 1, y = qp(2, b, P), ans = qp(y, P - 2, P);
	for (int i = 1; i < a; i ++ ){
		x = x * (b + i - 1) % P * qp(i, P - 2, P) % P;
		y = y * 2 % P;
		ans = (ans + x * qp(y, P - 2, P) % P) % P;
	}
	cout << ans << "\n";
	return 0;
}

I.Yet Another FFT Problem?

题意:

给定两个序列 \(a\) 和 \(b\),判断存不存在 \(\lvert a_i - a_j \rvert = \lvert b_k - b_l \rvert\)(\(i != j, k != l\)),若存在输出 \(i, j, k, l\),否则输出 -1。

思路:

转化一下等式,变成 \(a_i + b_l = a_j + b_k\),因为两个序列中的最大值之和只有 \(2e7\),所以可以暴力枚举两个数之和。
还要考虑一个特殊情况,\(a_i = a_j, b_k = b_l\)。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e7 + 10;
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	int n, m;
	cin >> n >> m;
	vector <int> a(n + 1), b(m + 1);
	for (int i = 1; i <= n; i ++ )
		cin >> a[i];
	for (int i = 1; i <= m; i ++ )
		cin >> b[i];
	vector <int> fa(N), fb(N), ans(4), A, B;
	for (int i = 1; i <= n; i ++ ){
		if (fa[a[i]] == 0){
			fa[a[i]] = i;
			A.push_back(i);
		}
		else{
			ans[0] = fa[a[i]];
			ans[1] = i;
		}
	}
	for (int i = 1; i <= m; i ++ ){
		if (fb[b[i]] == 0){
			fb[b[i]] = i;
			B.push_back(i);
		}
		else{
			ans[2] = fb[b[i]];
			ans[3] = i;
		}
	}
	if (ans[0] && ans[2]){  //存在差为 0 的情况
		for (int i = 0; i < 4; i ++ )
			cout << ans[i] << " \n"[i == 3];
		return 0;
	}
	vector < array<int, 2> > f(N * 2);
	for (auto i : A){
		for (auto j : B){
			if (f[a[i] + b[j]][0] == 0){
				f[a[i] + b[j]] = {i, j};
			}
			else{
				cout << i << " " << f[a[i] + b[j]][0] << " " << j << " " << f[a[i] + b[j]][1] << "\n";
				return 0;
			}
		}
	}
	cout << "-1\n";
	return 0;
}

标签:10,qp,int,蔚来,LL,多校,cin,ans
来源: https://www.cnblogs.com/Hamine/p/16617462.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有