首页 > 其他分享 >AtCoder Beginner Contest 270

AtCoder Beginner Contest 270

时间:2022-09-25 23:55:28浏览次数:82  
标签:AtCoder le Beginner 10 int sum st 270 高桥

AtCoder 五十连练 第一练

AtCoder Beginner Contest 270

A - 1-2-4 Test

考试有三道题,分别是 \(1\) 分、\(2\) 分、\(4\) 分。高桥、青木和 Snuke 参加了这次考试。高桥得到 \(A\) 分,青木得到 \(B\) 分。

Snuke 解决了高桥和青木中至少一个人解决的所有问题,但没有解决他们两个都没有解决的任何问题。找到 Snuke 的分数。

可以证明,在这个问题的约束条件下,Snuke的分数是唯一确定的。

数据范围;\(0 \le A,B \le 7\)。

Code.

#include<bits/stdc++.h>
using namespace std;
int a,b,st[10],sum;
int main()
{
	cin>>a>>b;
	if(a == 5 || b == 5) st[1]=st[3]=1;
	if(a == 1 || b == 1) st[1]=1;
	if(a == 2 || b == 2) st[2]=1;
	if(a == 4 || b == 4) st[3]=1;
	if(b == 3 || a == 3) st[1]=st[2]=1;
	if(a == 6 || b == 6) st[2]=st[3]=1;
	if(a == 7 || b == 7) st[1]=st[2]=st[3]=1;
	if(st[1]) sum+=1;
	if(st[2]) sum+=2;
	if(st[3]) sum+=4;
	cout<<sum<<endl;
	return 0;
}

B - Hammer

赤桥在数轴的原点。他想在坐标 \(X\) 处达到一个目标。在 \(Y\) 坐标处有一堵墙,高桥刚开始无法越过。然而,在坐标 \(Z\) 处捡起锤子后,他可以摧毁那堵墙并通过。

确定高桥是否能达到目标。如果可以的话,求出他到达目的地所需的最小总距离。

数据范围:$ -1000 \le X,Y,Z \le 1000$。

Code.

#include<bits/stdc++.h>
using namespace std;
int x,y,z;
int main()
{
	scanf("%d%d%d",&x,&y,&z);
	if(y > 0 && y < z && x > y) return puts("-1"),0;
	else if(y < 0 && z < y && x < y) return puts("-1"),0;
	if(x > 0 && (y > x || y < 0)) return printf("%d\n",x),0;
	else if(x < 0 && (y < x || y > 0)) return printf("%d\n",abs(x)),0;
	int sum=abs(z); sum+=abs(y-z); sum+=abs(y-x);
	cout<<sum<<endl;
	return 0;
}

C - Simple path

有一个有 \(N\) 个顶点的树 \(T\)。第 \(i\) 条边 \((1 \le i \le N-1)\) 连接顶点 \(U_i\) 和顶点 \(V_i\)。

给定 \(T\) 中的两个不同顶点 \(X\) 和 \(Y\)。按顺序列出从顶点 \(X\) 到顶点 \(Y\) 的简单路径上的所有顶点,包括端点。

可以证明,对于树中任意两个不同的顶点 \(a\) 和 \(b\),存在一条唯一的从 \(a\) 到 \(b\) 的简单路径。

数据范围:\(1 \le N \le 2 \times 10^5\)。

Code.

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int h[N],ne[N<<1],e[N<<1],idx,n,x,y,pre[N],st[N];
void add(int u,int v) {ne[++idx]=h[u],e[idx]=v,h[u]=idx;}
void dfs(int u,int father)
{
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i]; if(j == father) continue ;
		dfs(j,u); pre[j]=u;
	}
}
stack<int> pl;
int main()
{
	memset(h,-1,sizeof h); memset(pre,-1,sizeof pre);
	scanf("%d%d%d",&n,&x,&y);
	for(int i=1,u,v;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		add(u,v); add(v,u);
	}
	dfs(x,0); 
	for(int i=y;~i;i=pre[i]) pl.push(i);
	while(! pl.empty()) {cout<<pl.top() <<" "; pl.pop();}
	return 0;
}

D - Stones

高桥和青木将玩一个用顺序 \((A_1,...,A_K)\) 取石头的游戏。

一堆石头最初有 \(N\) 个。两位选手轮流执行下面的操作,高桥先走。选择一个 \(A_i\),它最多是一堆石头的当前数量。从堆中移除 \(A_i\) 石头。当堆里没有石头时,游戏就结束了。

如果两名玩家都试图在游戏结束前最大化他们移走的石头的总数,高桥将移走多少石头?

数据范围:\(1 \le N \le 10 ^4,1 \le K \le 100\)。

博弈论 dp,设 \(dp[i]\) 表示高桥在第 \(i\) 个石头时能取的最大值,高桥取走 \(a[i]\) 时就有,\(dp[i] = \max (dp[i],i-dp[i-a[j]])\),可以在 \(O(nk)\) 的时间内解决。

Code.

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int a[N],f[N],n,k;
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<=k;i++) scanf("%d",a+i);
	for(int i=0;i<=n;i++)
		for(int j=1;j<=k;j++)
			if(a[j] <= i) f[i]=max(f[i],i-f[i-a[j]]);
	printf("%d",f[n]); 
	return 0;
}

E - Apple Baskets on Circle

一共有 \(N\) 个篮子,编号为 \(1,2,...,N\),排成一圈。对于每一个 \(1 \le i \le N-1\),第 \(i+1\) 个篮子在第 \(i\) 个篮子的右边,第 \(1\) 个篮子在第 \(N\) 个篮子的右边。

现在篮子里有 \(A_i\) 个苹果。高桥从 \(1\) 号篮筐前开始,重复下面的动作。如果他面对的篮子里有一个苹果,就拿一个吃掉。然后,不管他现在是否吃了苹果,都去右边的下一个篮子里。

求高桥总共吃了 \(K\) 个苹果时,每个篮子里还剩多少苹果。

数据范围:\(1 \le N \le 10^5,0 \le A_i,K \le 10^{12}\)。

有一个很典的二分,我们可以二分转了多少圈,吃的苹果总和与 \(K\) 相比较,取到一个最接近 \(K\) 的值,修改所有的 \(A_i\) ,后暴力的走完剩下的半圈,修改,统计答案。

Code.

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,k,a[N],tmp,res;
bool check(int mid)
{
	int sum=0; for(int i=1;i<=n;i++) sum+=min(a[i],mid);
	return sum <= k;
}
signed main()
{
	scanf("%lld%lld",&n,&k);
	for(int i=1;i<=n;i++) scanf("%lld",a+i);
	int l=0,r=k;
	while(l <= r)
	{
		int mid=(l+r)>>1ll;
		if(check(mid)) res=mid,l=mid+1;
		else r=mid-1;
	}
	for(int i=1;i<=n;i++) {tmp=min(a[i],res); a[i]-=tmp; k-=tmp;}
	for(int i=1;i<=n;i++) {if(k == 0) break ; if(a[i]) {a[i]--; k--;}}
	for(int i=1;i<=n;i++) printf("%lld ",a[i]);
	return 0;
}

F - Transportation

AtCoder 共和国有 \(N\) 个岛屿。最初,这些岛屿都没有机场或港口,岛屿之间也没有公路。高桥国王将提供这些岛屿之间的交通工具。具体来说,他可以以任何顺序执行以下操作的任意次数。

选择一个整数 \(i\),使 \(1 \le i \le N\),并支付成本 \(Y_i\) 在岛 \(i\) 上建造港口。选择整数 \(i\),使\(1 \le i \le M\),支付成本 \(Z_i\),修建双向连接 \(A_i\) 岛和 \(B_i\) 岛的道路。

高桥的目标是让每一对不同的岛屿 \(U\) 和 \(V\) 都能够从岛屿 \(U\) 到达岛屿 \(V\),即当玩家能够以任何顺序执行以下行动的任意次数时。

当岛屿 \(S\) 和 \(T\) 都有机场时,岛屿 \(S\) 与 \(T\) 相连通;当岛屿 \(S\) 和 \(T\) 都有港口时,岛屿 \(S\) 与 \(T\) 相连通;当岛屿 \(S\) 和 \(T\) 都有道路时,岛屿 \(S\) 与 \(T\) 相连通。

找到的最低总成本高桥需要支付来实现他的目标。

数据范围:\(1 \le N,M \le 2 \times 10^5,1 \le X_i,Y_i,Z_i \le 10^9\)。

最小代价使图相连通,考虑最小生成树,针对港口与机场,我们可以通过建立虚拟源点的方法把点权转化成边权,因为最小生成树会把虚拟源点也算进去,所以如果加入港口或机场,就一定会使用它,所以需要分类讨论:只用路;路 + 港口;路 + 机场;路 + 港口 + 机场。

跑四遍 \(kruskal\) 就可以了,需要判断是否完全连通,注意并查集数组所连的点应该时两个点的父节点,#define int long long

Code.

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10,M=2e6+10;
int f[N],n,m,x[N],y[N],u[N],v[N],w[N],sx,sy,res=LONG_MAX,ans;
struct node 
{
	int u,v,w;
	bool operator < (const node &o) const {
		return w < o.w;
	}
}; vector<node> e;
int find(int x) {if(f[x] != x) f[x]=find(f[x]); return f[x];}
void kruskal(int d)
{
	ans=0; int yl=0; iota(f+1,f+n+10,1); sort(e.begin(),e.end());
	for(auto pl : e)
	{
		int pu=find(pl.u),pv=find(pl.v);
		if(pu == pv) continue ;
		f[pv]=pu; ans+=pl.w; yl++;
	}
	if(yl < d-1) ans=LONG_MAX;
}
signed main()
{
	
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",x+i);
	for(int i=1;i<=n;i++) scanf("%lld",y+i);
	for(int i=1;i<=m;i++) scanf("%lld%lld%lld",u+i,v+i,w+i);
	
	for(int i=1;i<=m;i++) e.emplace_back(node{u[i],v[i],w[i]});
	kruskal(n); res=min(res,ans);
	
	for(int i=1;i<=n;i++) e.emplace_back(node{i,n+1,x[i]});
	kruskal(n+1); res=min(res,ans);
	
	for(int i=1;i<=n;i++) e.emplace_back(node{i,n+2,y[i]});
	kruskal(n+2); res=min(res,ans);
	
	e.clear();
	for(int i=1;i<=m;i++) e.emplace_back(node{u[i],v[i],w[i]});
	for(int i=1;i<=n;i++) e.emplace_back(node{i,n+2,y[i]});
	kruskal(n+1); res=min(res,ans);
	
	printf("%lld\n",res);
	return 0;
}

标签:AtCoder,le,Beginner,10,int,sum,st,270,高桥
From: https://www.cnblogs.com/EastPorridge/p/16729455.html

相关文章

  • AtCoder Beginner Contest 270
    A.1-2-4Test水题。B.Hammer分裂讨论。codeC.Simplepath一遍dfs就完了,怎么还有这种搜索题!codeD.Stones观察数据范围,\(O(NK)\)可过。\(dp_i\)表示\(i\)......
  • ABC270D(fake)
    ……你家E比D水……题意有$N$颗石子,每次可以拿$A_1$或$A_2$或……或$A_K$颗石子。Takahashi是先手,Snuke是后手。他们都想让自己取的石子数尽......
  • ABC 270 C - Simple path(树+dfs)
    第一次写出比较正经的树+dfs,这不得写篇博客题目大意:给定一棵树,具有n个节点,给定n-1条边,给定一个起点和终点,让我们输出从起点到终点的路径。SampleInput1Copy5......
  • AtCoder Beginner Contest 270
    咕咕咕。D-Stones冲了发贪心,然后WA。然后想了个DP,就令\(dp_{n,0/1}\)表示石头总数为\(n\)时,先手/后手最多能拿多少个石头,然后跑个\(O(nk)\)的DP就完事了。......
  • AtCoder Beginner Contest 268(D-E)
    D-UniqueUsername 题意:给出n个字符串,以任意顺序排列,然后在每两个字符串中间加最少一个"_",然后给出m个字符串,问是否能得出一个字符串,不在这m个字符串中,并且长度在3-16......
  • 关爱2700多万听障者,手语服务助力无声交流
    如果有一天,周遭的世界突然变得很安静,动听美妙的音乐,在你看来只是沉寂;振奋人心的演讲,对你而言只是默剧;大自然的千里莺啼,于你来说也只是画卷。你会不会感到害怕?而有这么一群......
  • AtCoder Beginner Contest 043 题解
    欢迎来到我的算法小屋前言 TaskNameAChildrenandCandies(ABCEdit)BUnhappyHacking(ABCEdit)CBeTogetherDUnbalancedA1)题目描述2......
  • Atcoder 269
    T1:计算(a+b)*(c-d)输出字符串点击查看代码#include<bits/stdc++.h>usingi64=longlong;intmain(){std::ios::sync_with_stdio(false);std::c......
  • AtCoder Beginner Contest 258
    AtCoderBeginnerContest258LinkA-When?模拟即可.点击查看代码#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;intmain(){intn;......
  • AtCoder Beginner Contest 269
    比赛链接A模拟即可。点击查看代码#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;inta,b,c,d;signedmain(){ cin>>a>>b>>c>>d; cout<<(......