@Dmaxiya
2018-08-17T10:20:46.000000Z
字数 3485
阅读 976
Codeforces
Contests 链接:Educational Codeforces Round 33
过题数:3
排名:813/9628
、 和 三个人轮流玩一个游戏,这个游戏没有平局,三个人玩游戏的规则如下:
- 由 和 先进行游戏, 在旁边旁观;
- 上一局游戏失败的人退出游戏,旁观下一局的比赛,上一局旁观的人继续与获胜的人进行游戏。
现在他们进行了 轮游戏,并记录下了每一局获胜的人,现在要求检查这个记录是否是可能出现的情况(例如上一局失败的人不可能在下一局继续进行游戏)。
第一行为一个正整数 ,接下来 行每行为一个整数 ,分别对应 、 和 ,表示第 局获胜的人。
如果这种结果是可能出现的,输出 ,否则输出 。
输入 | 输出 | 提示 |
---|---|---|
3 1 1 2 |
YES | 可能的情况为: 1. 获胜, 替换 进行游戏; 2. 获胜, 继续进行游戏; 3. 获胜。 |
2 1 2 |
NO | 由于 在第一局游戏中失败了,所以他不可能是第二局游戏的获胜者。 |
按照题意模拟,如果出现旁观者获胜的情形,就是非法的情况,否则总是合法的。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
#define LL long long
int n, x;
int num[3];
int main() {
#ifdef Dmaxiya
freopen("test.txt", "r", stdin);
#endif // Dmaxiya
ios::sync_with_stdio(false);
while(scanf("%d", &n) != EOF) {
bool flag = true;
for(int i = 0; i < 3; ++i) {
num[i] = i + 1;
}
for(int i = 0; i < n; ++i) {
scanf("%d", &x);
if(x == num[0]) {
swap(num[1], num[2]);
} else if(x == num[1]) {
swap(num[0], num[2]);
} else {
flag = false;
}
}
if(flag) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}
如果一个数字的二进制表示是由 位连续的 与 位连续的 组成,那么这个数字就是一个漂亮的数,换一句话说,如果一个数字能够表示成某个整数 的 ,那么它就是漂亮的数。现在给定一个整数 ,询问最大的能整除 的漂亮的数。
输入只包含一个整数 。
输出最大的能整数 的漂亮的数。
输入 | 输出 |
---|---|
3 | 1 |
992 | 496 |
从 到 枚举每一个数字暴力判断找到第一个满足条件的数字即可。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
#define LL long long
int n;
int lowbit(int x) {
return x & (-x);
}
bool judge(LL x) {
for(int i = 1; i < 30; ++i) {
if(x == ((1LL << i) - 1) * (1LL << (i - 1))) {
return true;
}
}
return false;
}
int main() {
#ifdef Dmaxiya
freopen("test.txt", "r", stdin);
#endif // Dmaxiya
ios::sync_with_stdio(false);
while(scanf("%d", &n) != EOF) {
int ans;
for(int i = n; i > 0; --i) {
if(judge(i) && n % i == 0) {
ans = i;
break;
}
}
printf("%d\n", ans);
}
return 0;
}
在玩一款游戏,这款游戏的目标是将谣言散播到所有的游戏人物,总共有 个游戏人物, 每将谣言告诉给一个人物并要他把谣言告诉他的朋友,就需要 的代价, 个人物中有 对朋友,如果 和 是朋友,那么 就会把谣言告诉 并且在告诉的过程中是免费的。问 要完成游戏任务所需要的最小的代价。
第一行为两个整数 ,第二行为 个整数 ,接下去 行每行两个整数 ,表示第 个人和第 个人是朋友。
输出最小代价。
输入 | 输出 | 提示 |
---|---|---|
5 2 2 5 3 4 8 1 4 4 5 |
10 | 最优的选择是将谣言传给第 个人,这样第 个人就会把谣言传给第 个人,第 个人会继续传给第 个人,当然他也需要贿赂第 和第 个人。 |
10 0 1 2 3 4 5 6 7 8 9 10 |
55 | 需要贿赂所有人。 |
10 5 1 6 2 7 3 8 4 9 5 10 1 2 3 4 5 6 7 8 9 10 |
15 | 最优的选择是贿赂第 个人。 |
能够互相散播谣言的组成了一个连通块,只要选择每个连通块中代价最小的一个,就可以以这个代价将谣言散播到这个连通块,连通块的最小值用并查集进行维护。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 100000 + 100;
int n, m, u, v;
LL ans;
int fa[maxn];
LL Min[maxn];
bool vis[maxn];
void Init() {
for(int i = 1; i <= n; ++i) {
fa[i] = i;
vis[i] = false;
}
}
int Find(int x) {
return (x == fa[x]? x: fa[x] = Find(fa[x]));
}
void unit(int x, int y) {
int xx = Find(x);
int yy = Find(y);
fa[xx] = yy;
Min[yy] = min(Min[xx], Min[yy]);
}
int main() {
#ifdef Dmaxiya
freopen("test.txt", "r", stdin);
#endif // Dmaxiya
ios::sync_with_stdio(false);
while(scanf("%d%d", &n, &m) != EOF) {
ans = 0;
Init();
for(int i = 1; i <= n; ++i) {
scanf("%I64d", &Min[i]);
}
for(int i = 0; i < m; ++i) {
scanf("%d%d", &u, &v);
unit(u, v);
}
for(int i = 1; i <= n; ++i) {
int f = Find(i);
if(!vis[f]) {
vis[f] = true;
ans += Min[f];
}
}
printf("%I64d\n", ans);
}
return 0;
}