Codeforces round #446 (div2)

比赛链接

(恩。。。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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值