AtCoder Beginner Contest 160题解
Posted johnran
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 160题解相关的知识,希望对你有一定的参考价值。
A. 签到题1。
#include<bits/stdc++.h> #define fi first #define sd second #define lson (nd<<1) #define rson (nd+nd+1) #define PB push_back #define mid (l+r>>1) #define MP make_pair #define SZ(x) (int)x.size() using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; inline int read(){ int res=0, f=1;char ch=getchar(); while(ch<‘0‘|ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){res=res*10+ch-‘0‘;ch=getchar();} return res*f; } const int MAXN = 200‘005; const int MOD = 1000000007; void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;} int mulmod(int a, int b){return 1ll*a*b%MOD;} int main(){ string s;cin>>s; int ok1=s[2]==s[3]; int ok2=s[4]==s[5]; if(ok1&&ok2)cout<<"Yes"; else cout<<"No"; return 0; }
B. 签到题2。
#include<bits/stdc++.h> #define fi first #define sd second #define lson (nd<<1) #define rson (nd+nd+1) #define PB push_back #define mid (l+r>>1) #define MP make_pair #define SZ(x) (int)x.size() using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; inline int read(){ int res=0, f=1;char ch=getchar(); while(ch<‘0‘|ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){res=res*10+ch-‘0‘;ch=getchar();} return res*f; } const int MAXN = 200‘005; const int MOD = 1000000007; void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;} int mulmod(int a, int b){return 1ll*a*b%MOD;} int main(){ int x;x=read(); int ans=(x/500)*1000; ans+=(x-(x/500)*500)/5*5; cout<<ans; return 0; }
C. 题意,给你一个环和一些点,可以从任意一个点出发,走遍所有点最短路程。
显然可以丢弃一段,枚举是哪一段即可。
#include<bits/stdc++.h> #define fi first #define sd second #define lson (nd<<1) #define rson (nd+nd+1) #define PB push_back #define mid (l+r>>1) #define MP make_pair #define SZ(x) (int)x.size() using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; inline int read(){ int res=0, f=1;char ch=getchar(); while(ch<‘0‘|ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){res=res*10+ch-‘0‘;ch=getchar();} return res*f; } const int MAXN = 200‘005; const int MOD = 1000000007; void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;} int mulmod(int a, int b){return 1ll*a*b%MOD;} int k, n; int A[MAXN]; int main(){ k=read();n=read(); for(int i=0;i<n;++i)A[i]=read(); int mx=0; for(int i=0;i<n;++i){ if(i==n-1){ mx=max(mx,k-A[n-1]+A[0]); }else{ mx=max(mx,A[i+1]-A[i]); } } cout<<k-mx; return 0; }
D. 题意,给一条链,和一条额外的边,问长度为1:N-1的最短路有多少条?
O(n^2)枚举。
#include<bits/stdc++.h> #define fi first #define sd second #define lson (nd<<1) #define rson (nd+nd+1) #define PB push_back #define mid (l+r>>1) #define MP make_pair #define SZ(x) (int)x.size() using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; inline int read(){ int res=0, f=1;char ch=getchar(); while(ch<‘0‘|ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){res=res*10+ch-‘0‘;ch=getchar();} return res*f; } const int MAXN = 2‘005; const int MOD = 1000000007; void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;} int mulmod(int a, int b){return 1ll*a*b%MOD;} int ans[MAXN]; int main(){ int n, x, y; n=read();x=read();y=read(); for(int i=1;i<=n;++i){ for(int j=i+1;j<=n;++j){ int t=min(j-i,1+abs(i-x)+abs(j-y)); ++ans[t]; } } for(int i=1;i<=n-1;++i){ cout<<ans[i]<<endl; } return 0; }
E. 要吃掉X个红苹果,Y个绿苹果,还有c个无色的苹果,每一个都有一定的价值,问最后最大价值?
分别排序之后,把前X大和前Y大的丢进堆里,对无色的正向扫,当堆顶部的小于无色的价值时出堆。
#include<bits/stdc++.h> #define fi first #define sd second #define lson (nd<<1) #define rson (nd+nd+1) #define PB push_back #define mid (l+r>>1) #define MP make_pair #define SZ(x) (int)x.size() using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; inline int read(){ int res=0, f=1;char ch=getchar(); while(ch<‘0‘|ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){res=res*10+ch-‘0‘;ch=getchar();} return res*f; } const int MAXN = 200‘005; const int MOD = 1000000007; void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;} int mulmod(int a, int b){return 1ll*a*b%MOD;} int a,b,c; int x,y; int A[MAXN], B[MAXN], C[MAXN]; priority_queue<int,vector<int>, greater<int>> q; int main(){ x=read();y=read(); a=read();b=read();c=read(); for(int i=1;i<=a;++i)A[i]=read(); for(int i=1;i<=b;++i)B[i]=read(); for(int i=1;i<=c;++i)C[i]=read(); sort(A+1,A+1+a); sort(B+1,B+1+b); sort(C+1,C+1+c); LL ans=0; for(int i=a;i>=a-x+1;--i)q.push(A[i]), ans+=A[i]; for(int i=b;i>=b-y+1;--i)q.push(B[i]), ans+=B[i]; for(int i=c;i>=1;--i){ if(C[i]>q.top()){ ans-=q.top(); q.pop(); q.push(C[i]); ans+=C[i]; } } cout<<ans; return 0; }
F. 给你一颗n个节点的树,依次放入1-n,放置的条件是这条边的另一个点已经放置了数字,求把1分别放置在节点1-n的方案数。
因为要求把1放在1-n号节点上的方案数,明示了换根dp(或许还有其他做法,但我不会嘿嘿。先考虑以把1放在一号节点的时候怎么数操作数。
设pre[v]是以v为根的子树的安排方式数。这个时候就是一个简单的乘法原理,先选再放进子树安排。第一次dfs就能处理出所有的pre[]。在换根的时候
我们首先要考虑到以u的儿子v为根的时候,我们首先要得到u作为v子树的pre[u]。这个显然(可能需要在纸上稍微写一下,原理就是先选再排)是ans[u]/(pre[v]*C(n-1,sz[v])),知道这个之后,得到ans[v]不过就是为u
这个子树重新选取一些数字而已,这个显然是C(n-1,n-sz[v])种可能。根据计算u答案的方法,直接套用到v上即可,具体见代码。
#include<bits/stdc++.h> #define fi first #define sd second #define lson (nd<<1) #define rson (nd+nd+1) #define PB push_back #define mid (l+r>>1) #define MP make_pair #define SZ(x) (int)x.size() using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; inline int read(){ int res=0, f=1;char ch=getchar(); while(ch<‘0‘|ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){res=res*10+ch-‘0‘;ch=getchar();} return res*f; } const int MAXN = 200‘005; const int MOD = 1000000007; void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;} int mulmod(int a, int b){return 1ll*a*b%MOD;} #define go(e,u) for(int e=head[u];e;e=Next[e]) int to[MAXN<<1],Next[MAXN<<1],head[MAXN],tol; void add_edge(int u,int v){ Next[++tol]=head[u];to[tol]=v;head[u]=tol; Next[++tol]=head[v];to[tol]=u;head[v]=tol; } int ans[MAXN]; int cnt[MAXN], pre[MAXN], tp[MAXN]; int sz[MAXN]; int fac[MAXN], inv[MAXN], n; int powmod(int x, int y){ int res=1; while(y){ if(y&1)res=1ll*res*x%MOD; y>>=1; x=1ll*x*x%MOD; } return res%MOD; } void init(){ fac[1]=fac[0]=1; for(int i=2;i<=n;++i)fac[i]=1ll*fac[i-1]*i%MOD; inv[0]=inv[1]=1; for(int i=2;i<=n;++i)inv[i]=1ll*MOD-1ll*MOD/i*inv[MOD%i]%MOD; for(int i=2;i<=n;++i)inv[i]=1ll*inv[i-1]*inv[i]%MOD; } int C(int n, int m){ return 1ll*fac[n]*inv[m]%MOD*inv[n-m]%MOD; } void dfs1(int u, int f){ sz[u]=1;pre[u]=1; go(e,u){ int v=to[e]; if(v==f) continue; dfs1(v,u); sz[u]+=sz[v]; pre[u]=1ll*pre[u]*pre[v]%MOD*C(sz[u]-1,sz[v])%MOD; } } void dfs2(int u, int f){ ans[u]=1ll*tp[u]*pre[u]%MOD*C(n-1,n-sz[u])%MOD; go(e,u){ int v=to[e]; if(v==f)continue; tp[v]=1ll*ans[u]*powmod(1ll*pre[v]*C(n-1,sz[v])%MOD,MOD-2)%MOD; dfs2(v,u); } } int main(){ n=read(); for(int i=1;i<n;++i){ int u, v; u=read(); v=read(); add_edge(u,v); } init(); dfs1(1,0); tp[1]=1; dfs2(1,0); for(int i=1;i<=n;++i)cout<<ans[i]<<endl; return 0; } /* 8 1 2 2 3 3 4 3 5 3 6 6 7 6 8 40 280 840 120 120 504 72 72 */
以上是关于AtCoder Beginner Contest 160题解的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解