CF 2022寒假练习
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
链接
题目大意
现有一排 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
链接
题目大意
公园是一棵树,其中有 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</