CF 2022寒假练习

CF 2022寒假练习

CF_2A Winner

链接

CF_2A Winner

题目大意

有一个游戏,由 n n n个玩家参与,每一轮会有一个玩家获得 s s s点数。游戏最后一轮结束后,点数最多的玩家获胜。如果游戏结束后,由多个玩家获得最多点数 m m m,则他们当中最先获得至少 m m m点的玩家获胜。

解析

进行两遍模拟,第一遍求出所有点数最多的玩家,第二遍求出最终获胜者。

代码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
using namespace std;
struct str
{
   
	int val,tim;
}edmax[1001],x;
int n,p[1001],tot0[1001],tot1[1001],cnt,maxx,sta[2000001],ans;
string s[1001],lst[1001];
bool flag[1001];
map<string,int> m;
bool cmp(str a,str b)
{
   
	if(a.val>b.val)
		return true;
	else if(a.val==b.val&&a.tim<b.tim)
		return true;
	else
		return false;
}
int main()
{
   
	for(int i=1;i<=1000;i++)
		tot0[i]=tot1[i]=1000000;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
   
		cin>>s[i];
		scanf("%d",&p[i]);
		if(!m[s[i]])
		{
   
			cnt++;
			m[s[i]]=cnt;
			lst[cnt]=s[i];
		}
		tot0[m[s[i]]]+=p[i];
	}
	for(int i=1;i<=cnt;i++)
		maxx=max(maxx,tot0[i]);
	for(int i=1;i<=n;i++)
	{
   
		tot1[m[s[i]]]+=p[i];
		if(tot1[m[s[i]]]>=maxx&&tot0[m[s[i]]]==maxx)
		{
   
			ans=m[s[i]];
			break;
		}
	}
	cout<<lst[ans];
	return 0;
}

CF_545C Woodcutters

链接

CF_545C Woodcutters

题目大意

现有一排 n n n颗树,第 i i i棵树的高度为 a i a_i ai。主人公要砍树,被砍的树可能往左倒或往右倒,求在不砸到其他树的情况下,主人公最多能砍多少棵树。

解析

动态规划,对每棵树,讨论不砍、砍下往左倒、砍下往右倒三种情况,看如何使当前砍树的数量最大化。注意,如果某棵树不砍,那么它要继承上一棵树的状态。

代码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
struct str
{
   
	int tot,maxx;
}f[100001][2];
int n,x[100001],h[100001],ans;
bool flag0,flag1;
bool check0(int p)
{
   
	for(int i=p;1<=i&&x[p]-h[p]<=x[i];i--)
		if(i!=p)
			return false;
	return true;
}
bool check1(int p)
{
   
	for(int i=p;i<=n&&x[i]<=x[p]+h[p];i++)
		if(i!=p)
			return false;
	return true;
}
int main()
{
   
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&x[i],&h[i]);
	f[0][1].maxx=-2000000000;
	for(int i=1;i<=n;i++)
	{
   
		flag0=false;
		if(check0(i))
		{
   
			flag0=true;
			f[i][0].tot=f[i-1][0].tot+1;
			if(f[i-1][1].maxx<x[i]-h[i])
				f[i][0].tot=max(f[i][0].tot,f[i-1][1].tot+1);
		}
		if(!flag0)
		{
   
			f[i][0].tot=f[i-1][0].tot;
			f[i][0].maxx=f[i-1][0].maxx;
		}
		flag1=false;
		if(check1(i))
		{
   
			flag1=true;
			f[i][1].tot=max(f[i-1][0].tot+1,f[i-1][1].tot+1);
			f[i][1].maxx=x[i]+h[i];
		}
		if(!flag1)
		{
   
			f[i][1].tot=f[i-1][1].tot;
			f[i][1].maxx=f[i-1][1].maxx;
		}
	}
	ans=max(f[n][0].tot,f[n][1].tot);
	printf("%d",ans);
	return 0;
}

CF_580C Kefa and Park

链接

CF_580C Kefa and Park

题目大意

公园是一棵树,其中有 n n n个餐馆,其中某些餐馆有猫。主人公害怕猫,他希望自己去餐馆的路上连续遇见的猫不超过 m m m只,求主人公最多能去的餐馆数。

解析

一遍树上DFS即可,剪枝时注意阻止主人公的猫是“连续遇见”的。

代码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
struct str
{
   
	int to,nxt;
}edg[100001];
int n,m,a[100001</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值