Codeforces Round #613 (Div. 2)

Codeforces Round #613 (Div. 2)

https://codeforces.com/contest/1285

A. Mezo Playing Zoma

直接输出n+1

B. Just Eat It!

题意:A获得的代价是所有a[i]之和,B获得的是a数组中任选一段的和的最大值,问A获得的代价是否严格大于B
思路:首先令dp[i]为选取a[i]能够获得的最大代价,可以由dp[i-1]+a[i]转移过来或者只选取a[i],两者取最大值即可,然后B不能全选,可用一个cnt数组记录取dp[i]的时候选了多少个数

#include<bits/stdc++.h>
#define MAXN 100005
#define ll long long
using namespace std;
int n;
const ll INF = 1e11;
ll a[MAXN];
ll sum,dp[MAXN],maxn,cnt[MAXN];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		sum = 0;
		dp[0] = cnt[0] = 0;
		maxn = -INF;
		for(int i = 1;i <= n;++i)
		{
			scanf("%lld",&a[i]);
			sum += a[i];
		}
		for(int i = 1;i <= n;++i)
		{
			if(dp[i-1] + a[i] > a[i] && cnt[i-1]+1<n)
			{
				dp[i] = dp[i-1]+a[i];
				cnt[i] = cnt[i-1] + 1;
			}
			else
			{
				dp[i] = a[i];
				cnt[i] = 1;
			}
			maxn = max(maxn,dp[i]);
		}
		if(sum > maxn)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}

C. Fadi and LCM

思路:首先a,b一定互质,不然如果有公约数则将公约数约去lcm不变但max值能够减小,这将就变成了将X拆成两个互质的数使最大值最小

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll INF = 1e13;
ll x;
int t;
long long gcd(long long a,long long b)
{
	return b?gcd(b,a%b):a;
}
int main()
{
	while(~scanf("%lld",&x))
	{
		ll minn = INF,a,b;
		for(ll i = 1;i * i <= x;++i)
		{
			if(x % i == 0 && gcd(i,x/i) == 1)
			{
				if(max(i,x/i) < minn)
					minn = max(i,x/i),a = i,b = x/i;
			}
		}
		printf("%lld %lld\n",a,b);
	}
	return 0;
}

D. Dr. Evil Underscores

思路:首先将所有数字放到一个01字典树中,对于一个位置,如果0号儿子和1号儿子都不存在则它的儿子能够返回的最大值即为0,只有一个儿子有的话那么这一位肯定能全变成0,往下一次走即可,两个儿子都存在那么这一位对最大值肯定有贡献,应当让这一位之后的贡献最小

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
int tmp,n,tr[MAXN * 30][2],cnt;
inline void insert(int x)
{
	int p = 0,d;
	for(int i = 29;i >= 0;--i)
	{
		d = (x >> i)&1;
		if(tr[p][d])
			p = tr[p][d];
		else
		{
			tr[p][d] = ++cnt;
			p = cnt;
			memset(tr[p],0,sizeof(tr[p]));
		}
	}
}
int dfs(int p,int d)
{
	if(!tr[p][0] && !tr[p][1]) return 0;
	if(!tr[p][0]) return dfs(tr[p][1],d-1);
	if(!tr[p][1]) return dfs(tr[p][0],d-1);
	return (1<<d) + min(dfs(tr[p][0],d-1),dfs(tr[p][1],d-1));
}
int main()
{
	while(~scanf("%d",&n))
	{
		cnt = 0;
		memset(tr[0],0,sizeof(tr[0]));
		for(int i = 1;i <= n;++i)
		{
			scanf("%d",&tmp);
			insert(tmp);
		}
		int ans = dfs(0,29);
		printf("%d\n",ans);
	}
	return 0;
}

E. Delete a Segment

见https://blog.csdn.net/xing_mo/article/details/103943554

F. Classical?

待补

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值