Educational Codeforces Round 27

A

题意:把2 * n个人分成两组,使得无论两组的人怎么进行比赛 第一组的人始终都要保持全赢,如果两个人能力值相等两人都可以赢

思路:排序后只要保证n + 1个人的能力值大于第n个人的能力值即可

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 200 + 10;
int num[qq], n;

int main(){
	scanf("%d", &n);
	for(int i = 1; i <= 2 * n; ++i) {
		scanf("%d", num + i);
	}
	sort(num + 1, num + 1 + 2 * n);
	int l = 1, r = n + 1;
	if(num[r] > num[r - 1]) {
		puts("YES");
	} else {
		puts("NO");
	}
	return 0;
}


B

题意:给出一个数,要求左边三个数字的和等于右边三个数字的和,求最小改变数字的次数

思路:10的6次方枚举所有结果

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e5 + 10;
char st[10];
char ans[10];
int minx = 1e9;
void Dfs(int pos) {
	if(pos == 6) {
		int t1 = (ans[0] - '0') + (ans[1] - '0') + (ans[2] - '0');
		int t2 = (ans[3] - '0') + (ans[4] - '0') + (ans[5] - '0');
		if(t1 == t2) {
			int t = 0;
			for(int i = 0; i < 6; ++i) {
				if(st[i] != ans[i])	++t;
			}
			minx = min(minx, t);
		}
		return;
	}
	for(int i = 0; i < 10; ++i) {
		ans[pos] = i + '0';
		Dfs(pos + 1);
	}
}

int main(){
	scanf("%s", st);
	Dfs(0);
	printf("%d\n", minx);
	return 0;
}

C

题意:给出每个电视节目的播放起始时间和结束时间,你现在有两台电视机,要求完整不漏的看完所有节目,注意如果某个节目的结束时间和另外一个节目的开始时间相同不可以在同一台电视机上播放

思路:直接模拟两个电视机判断即可

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2e5 + 10;
struct Node {
	int l, r;
	bool operator < (const Node &w) const {
		if(l == w.l)	return r < w.r;
		return l < w.l;
	}
}node[qq];

int main(){
	int n;	scanf("%d", &n);
	for(int i = 0; i < n; ++i) {
		scanf("%d%d", &node[i].l, &node[i].r);
	}
	sort(node, node + n);
	int t1 = -1, t2 = -1;
	bool f = true;
	for(int i = 0; i < n; ++i) {
		if(t1 < t2) {
			if(t1 < node[i].l)	t1 = node[i].r;
			else if(t2 < node[i].l)	t2 = node[i].r;
			else	f = false;
 		} else {
 			if(t2 < node[i].l) t2 = node[i].r;
 			else if(t1 < node[i].l) t2 = node[i].r;
 			else	f = false;
 		}
	}
	if(f)	puts("YES");
	else	puts("NO");
	return 0;
}


D

题意:给出n次操作,你可以忽略 可以超车,不可以超车,速度最大限制以及无速度限制这些操作,问使得超车以及改变速度合法的前提下最少需要忽略多少次操作,每次超车可以覆盖前面所有的超车和不超车,速度最大限制和无速度限制一样

思路:直接模拟即可

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2e5 + 10;
struct Node {
	int t, speed;
	Node(){}
	Node(int _t, int _speed) : t(_t), speed(_speed){}
}a[qq], b[qq];
vector vt;

int main(){
	int n;	scanf("%d", &n);
	int cnt1, cnt2;
	cnt1 = cnt2 = 0;
	int t, speed;
	for(int i = 0; i < n; ++i) {
		scanf("%d", &t);
		if(t == 1 || t == 3) scanf("%d", &speed);
		else	speed = 0;
		if(t % 2 == 1)	a[cnt1++] = Node(t, speed);
		else	b[cnt2++] = Node(t, speed);
	}
	int ans = 0;
	speed = a[0].speed;
	for(int i = 1; i < cnt1; ++i) {
		if(a[i].t == 1) {
			speed = a[i].speed;
			while(!vt.empty() && speed > vt.back()) {
				vt.pop_back(), ans++;
			}
		} else if(a[i].t == 3) {
			vt.pb(a[i].speed);
			while(!vt.empty() && speed > vt.back()) {
				vt.pop_back(), ans++;
			}
		} else if(a[i].t == 5) {
			vt.clear();
		}
	}
	t = 0;
	for(int i = 0; i < cnt2; ++i) {
		if(b[i].t == 2) {
			ans += t;
			t = 0;
		} else if(b[i].t == 4) {
			t = 0;
		} else if(b[i].t == 6) {
			t++;
		}
	}
	printf("%d\n", ans);
	return 0;
}



G

题意:从1走到n要求边权异或最小

思路:vt[i]代表从1走到i的边权异或值,dis代表从1走到当前结点的异或值,那么对于环而言就是dis ^ vt[i] ^ 反向边的权值,loop里面存的是包含当前环之间异或的最小值

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2e5 + 10;
const int INF = 1e9 + 10;
vector loop;
vector > G[qq];
bool vis[qq];
LL vt[qq];
void Add(LL x) {
	for(int i = 0; i < (int)loop.size(); ++i) {
		x = min(x, x ^ loop[i]);
	}
	if(x)	loop.pb(x);
}
void Dfs(int u, LL dis) {
	vis[u] = true;
	vt[u] = dis;
	for(int i = 0; i < (int)G[u].size(); ++i) {
		int v = G[u][i].first;
		if(vis[v]) Add(vt[v] ^ dis ^ G[u][i].second);
		else	Dfs(v, dis ^ G[u][i].second);
	}
}

int main(){
	int n, m;	scanf("%d%d", &n, &m);
	for(int i = 0; i < m; ++i) {
		int x, y;	LL z;
		scanf("%d%d%lld", &x, &y, &z);
		G[x].pb(mk(y, z));
		G[y].pb(mk(x, z));
	}
	Dfs(1, 0);
	for(int i = 0; i < (int)loop.size(); ++i) {
		vt[n] = min(vt[n], vt[n] ^ loop[i]);
	}
	printf("%lld\n", vt[n]);
	return 0;
}


你可能感兴趣的:(codeforces)