Educational Codeforces Round 124 (Rated for Div. 2)

日常倒序
C.Fault-tolerant Network

题意分析: 有两排电脑, 每一排的电脑是左右互连的,现在要求你将上下两排的电脑连接起来, 形成容错网络: 即网络保持连接,尽管其中一台计算机出现故障。换句话说,如果一台计算机坏了(不管是哪台),网络就不会分裂成两个或多个部分。连接两台计算机的费用是 ∣ a i − b j ∣ |a_i - b_j| aibj

首先形成容错网络, 连四条边 是肯定可以的, 但不一定是最优的, 也可以连两条边, 也可以连三条边

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define x first
#define y second
typedef pair<int,int>PII;
#define debug printf("debug\n");

const int N = 5e5 + 10, INF = 0x3f3f3f3f, mod = 998244353;
int t;
int a[N], b[N], n;

void solve()
{
	cin >> n;
	for(int i = 1; i <= n; i ++ ) cin >> a[i];
	for(int i = 1; i <= n; i ++ ) cin >> b[i];


		 int v0 = INF, v1 = INF, v2 = INF, v3 = INF;
		for(int i = 1; i <= n; i ++ )
			v0 = min(v0, abs(a[1] - b[i])),  //得到每一条边的最小值
			v1 = min(v1, abs(a[n] - b[i])),
			v2 = min(v2, abs(b[1] - a[i])),
			v3 = min(v3, abs(b[n] - a[i]));	
		int ans = v0 + v1 + v2 + v3;   //四条边
		ans = min(ans, abs(a[1] - b[1]) + v1 + v3); //合并a1->bi b1->ai
		ans = min(ans, abs(a[n] - b[n]) + v0 + v2); //合并ai->bn an->bi 
		ans = min(ans ,abs(a[1] - b[n]) + v1 + v2); //合并a1->bi bn->ai
		ans = min(ans, abs(a[n] - b[1]) + v0 + v3); //合并ai->b1 an->bi

		ans = min(ans, abs(a[1] - b[1]) + abs(a[n] - b[n])); //合并两条
		ans = min(ans, abs(a[1] - b[n]) + abs(a[n] - b[1])); //合并两条

		cout << ans << '\n';
}




signed main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	 	cin >> t;
		while(t -- )solve();
}

B. Prove Him Wrong

题意分析: 给定长度 n n n, 存在一种操作使 a i = a j = ∣ a i − a j ∣ a_i = a_j = |a_i - a_j| ai=aj=aiaj, 是否存在长度为 n n n 的序列能够在任意操作下总和不会变小

题意分析: 为了去掉绝对值我们可以考虑使序列元素的值从小到大, 这样对于任意的 i , j i,j i,j 我们只要保证从左往右扫一遍, 从右往左扫一遍, 符合要求即可
从左往右扫 a i + a j ≥ 2 ∗ ( a j − a i ) a_i + a_j ≥ 2 * (a_j - a_i) ai+aj2(ajai) 得到 3 ∗ a i ≥ a j 3 * a_i ≥a_j 3aiaj
从右往左扫 a i + a j ≥ 2 ∗ ( a i − a j ) a_i + a_j ≥ 2 * (a_i - a_j) ai+aj2(aiaj) 3 ∗ a j ≥ a i 3 * a_j ≥ a_i 3ajai
所以只要右边元素是左边元素的三倍即可, 然后因为 a a a i n t int int 范围, 最大为 3 19 3^{19} 319, 所以 n n n 大于 19 19 19 都是不合法的

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define x first
#define y second
typedef pair<int,int>PII;
#define debug printf("debug\n");

const int N = 5e5 + 10, INF = 0x3f3f3f3f, mod = 998244353;
int t;
int pow2[100];
void solve()
{
	int n;
	cin >> n;
	if(n > 19) //不合法
		cout << "NO\n";
	else 
	{
		cout << "YES\n";
		for(int i = 1; i <= n; i ++ )  //直接枚举咯
			cout << pow2[i - 1] << " ";
	 		cout << '\n';
	}
}

signed main()
{
	pow2[0] = 1;   //预处理3的n次方
	for(int i = 1; i <= 19; i ++ ) pow2[i] = pow2[i - 1] * 3;
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	 	cin >> t;
		while(t -- )solve();
}

A. Playoff

题意: 给定整数 n n n, 每位运动员上标有一个数字, 该数字的范围是 1 1 1 ~ 2 n 2^n 2n, 从小到大相邻的两个数为一组, 一组中将决出一个赢家, 然后晋级下一轮, 每轮决胜规则是 当一组中运动员的编号之和为奇数, 小的获胜, 和为偶数时, 大的获胜, 请你输出最后获胜者的编号

分析: 不难发现经过第一轮后,只剩下了编号为奇数的运动员, 所以剩下的比赛中和都为偶数, 所以获胜者都是编号大的, 故发现第一轮先取小, 后面全取大, 那就是 2 n − 1 2 ^ n - 1 2n1

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define x first
#define y second
typedef pair<int,int>PII;
#define debug printf("debug\n");

const int N = 5e5 + 10, INF = 0x3f3f3f3f, mod = 998244353;
int t;
int pow2[100];
void solve()
{
	int n;
	cin >> n;
	 //n轮比赛
	cout << pow2[n] - 1 << '\n';
}

signed main()
{
	pow2[0] = 1;  //预处理2的次幂
	for(int i = 1; i <= 30; i ++ ) pow2[i] = pow2[i - 1] * 2;
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	 	cin >> t;
		while(t -- )solve();
}

写作不易, 给个赞吧!

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广西小蒟蒻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值