Codeforces round #446 (div2)

来源:互联网 发布:淘宝上买手机 编辑:程序博客网 时间:2024/06/15 11:53

比赛链接

(恩。。。noip后第一场cf,被虐得好惨啊。

主要是T2打错了一个字母找了1h...

居然只降了1分我感到很欣慰。。)


额,言归正传qwq.


A. Greed

题目大意:有一些可乐和杯子,告诉你每瓶可乐的多少的杯子的容量,问能不能把所有可乐放到两个杯子里。

做法:大水题,不解释。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int N = 100010;int n;int a[N];int main(){scanf("%d", &n); LL sum = 0;for (int i = 1; i <= n; i ++){int x; scanf("%d", &x);sum += x;}for (int i = 1; i <= n; i ++) scanf("%d", &a[i]);sort(a+1, a+1+n);if (sum <= a[n]+a[n-1]){puts("YES");} else {puts("NO");}return 0;}

B. Wrath

题目大意:有一些人排成一队,每个人会杀死他前面最多li个人,现在所有人同时开始杀人,问最后活着的有几个。

做法:把所有人杀的人看成一堆区间,然后按左端点排序,扫描一遍即可算出答案。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int N = 1000010;int n;struct Node{int l, r;}a[N];const bool cmp(const Node &x, const Node &y){return x.l < y.l;}int main(){scanf("%d", &n); int m = 0;for (int i = 1; i <= n; i ++){int x; scanf("%d", &x);if (!x || i == 1) continue;a[++ m].l = max(1, i-x);a[m].r = i-1;} int cnt = n;n = m; int ans = 0;if (n == 0){printf("%d\n", cnt);return 0;}sort(a+1, a+1+n, cmp);int l = a[1].l, r = a[1].r;for (int i = 2; i <= n; i ++){if (a[i].l > r){ans += r-l+1;l = a[i].l; r = a[i].r;} else {r = max(r, a[i].r);}}ans += r-l+1;printf("%d\n", cnt-ans);return 0;}

C. Pride

题目大意:有n个数字,每一次操作可以把相邻两个数中的一个变成这两个数的gcd,问最少几次把所有数变成1。

做法:首先如果数组中本来就有1,记1的个数为cnt1,那么肯定在n-cnt1步操作后就变成全1。

如果数组中本身没有1,那么一定需要有一个1,然后就可以在n-1步之后变成全1。

所以我们暴力枚举一下所有区间,计算一下答案即可。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int N = 2010;int n;int a[N];int main(){scanf("%d", &n); int cnt1 = 0;for (int i = 1; i <= n; i ++){scanf("%d", &a[i]);if (a[i] == 1) cnt1 ++;}if (cnt1 > 0){printf("%d\n", n-cnt1);return 0;} int ans = 1e9;for (int i = 1; i <= n; i ++){int x = a[i];for (int j = i+1; j <= n; j ++){x = __gcd(x, a[j]);if (x == 1){ans = min(ans, j-i+n-1);break;}}}if (ans == 1e9) puts("-1");else printf("%d\n", ans);return 0;}

D. Gluttony

题目大意:给一个数组a,让你构造一个数组b(b中元素和a中元素相同),使得a和b所有前缀和不相同。

做法:考虑一个构造方案,就是说把a从小到大排序以后,b中每一个数都放a对应位置的数的比它小的第一个数。

感觉有一点绕- - 呃形象点就是说,把a中所有元素都往前挪了一步,然后最小那个变成了最大那个。

然后正确性应该是显然的。。

#include<cstdio>#include<cstring>#include<algorithm>#define rep(i, x, y) for (int i = (x); i <= (y); i ++)using namespace std;const int N = 25;int n;int a[N], rk[N], b[N];const bool cmp(const int x, const int y){return a[x] < a[y];}int main(){scanf("%d", &n);rep(i, 1, n){scanf("%d", &a[i]);rk[i] = i;} sort(rk+1, rk+1+n, cmp);rep(i, 1, n-1){b[rk[i+1]] = a[rk[i]];}b[rk[1]] = a[rk[n]];rep(i, 1, n) printf("%d ", b[i]);return 0;}

=========================================================================

总结:

比赛时通过A,B,C,Rank 950,rating -1。

主要问题:T2细节问题导致错了好几次,时间严重浪费。

然后T3一开始没有想到,是问了某大佬才做出的qwq。

唉。。争取下次涨点rating...qwq。

原创粉丝点击