codeforces round #499(div2) 做题记录
Posted uuzlove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces round #499(div2) 做题记录相关的知识,希望对你有一定的参考价值。
codeforces round #499(div2) 做题记录
A. Stages
题意:
给你n个字母,你要选k个,你选择的相邻两个字母在字母表中必须满足中间至少隔一个字母,每个字母的权值是c-‘a’+1,求最小权值和。
k<=n<=50
题解:贪心,从前向后扫,满足题意的就加进去就可以了
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 55 4 using namespace std; 5 int n,k; 6 char s[maxn]; 7 int w[maxn]; 8 int main() 9 { 10 scanf("%d%d",&n,&k); 11 scanf("%s",s+1); 12 for(int i=1;i<=n;++i)w[s[i]-‘a‘+1]++; 13 int last=-1,tot=0,ans=0; 14 for(int i=1;i<=26;++i)if(w[i]&&i-last>1) 15 { 16 tot++;ans+=i;last=i; 17 if(tot==k)break; 18 } 19 if(tot<k)puts("-1");else printf("%d ",ans); 20 return 0; 21 }
B. Planning The Expedition
题意:
你有n个人,m个食品,每个食品有一个种类a_i,你现在要用这些食品喂饱这些人,每个人第一天吃了哪个种类的食品以后每天都必须吃这个种类的食品,求让这n个人生存的最大天数
n,m,a_i<=100
题解:
枚举天数,然后check一遍
1 #include<bits/stdc++.h> 2 #define maxn 105 3 using namespace std; 4 int n,m; 5 int c[maxn]; 6 int main() 7 { 8 scanf("%d%d",&n,&m); 9 for(int x,i=1;i<=m;++i)scanf("%d",&x),c[x]++; 10 for(int T=1;T<=1000;++T) 11 { 12 int tot=0; 13 for(int i=1;i<=100;++i)tot+=c[i]/T; 14 if(tot<n) 15 { 16 printf("%d ",T-1); 17 return 0; 18 } 19 } 20 return 0; 21 }
C. Fly
题意:
有n个星球,你要从1->2->3->……->n->1,每次起飞降落都要消耗燃料,消耗的燃料*系数=(飞船重量m+燃料重量),给定每次的系数a_i和b_i,求最少要带多少燃料
n,m<=1000
题解:
把起降的序列搞出来,然后从最后一次剩余燃料开始解方程即可,方程无解就是-1
1 #include<bits/stdc++.h> 2 #define maxn 1005 3 using namespace std; 4 const double eps=1e-7; 5 int n; 6 double m; 7 double a[maxn],b[maxn],c[maxn*2]; 8 int main() 9 { 10 scanf("%d",&n); 11 scanf("%lf",&m); 12 for(int i=1;i<=n;++i)scanf("%lf",&a[i]); 13 for(int i=1;i<=n;++i)scanf("%lf",&b[i]); 14 for(int i=1;i<=n;++i)c[i*2-2]=b[i],c[i*2-1]=a[i]; 15 c[0]=0;c[n*2]=b[1];n*=2; 16 for(int i=1;i<=n;++i) 17 { 18 if(c[i]-1<=eps) 19 { 20 puts("-1"); 21 return 0; 22 } 23 } 24 double t=0; 25 for(int i=n;i;--i) 26 { 27 t=(m+c[i]*t)/(c[i]-1); 28 } 29 printf("%.10lf ",t); 30 return 0; 31 }
D.Rocket
题意:
交互题
给你一个范围1~m,让你猜一个数x,每次系统会告诉你你猜的数y是y<x还是y=x还是y>x
但系统会说谎,具体来说,有一个长度为n的01序列,0表示说谎,1表示不说谎,系统按这个序列循环询问。
但你只知道n和m,并不知道序列,你要猜出这个数
n<=30,m<=1e9,询问次数<=60
题解:
首先我们可以询问1-n,如果猜中很好,如果没猜中那么答案肯定>i,所以这个序列就可以在n次询问被确定下来
然后二分就行了
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m; 4 int a[35]; 5 int main() 6 { 7 scanf("%d%d",&m,&n); 8 for(int i=0;i<n;++i) 9 { 10 printf("%d ",i+1); 11 fflush(stdout); 12 int opt; 13 scanf("%d",&opt); 14 if(opt==0) 15 { 16 return 0; 17 } 18 if(opt==1)a[i]=1; 19 if(opt==-1)a[i]=-1; 20 } 21 int l=1,r=m; 22 for(int T=0;T<30;++T) 23 { 24 int x=T%n; 25 int mid=(l+r)>>1; 26 printf("%d ",mid); 27 fflush(stdout); 28 int opt; 29 scanf("%d",&opt); 30 if(opt==0) 31 { 32 return 0; 33 } 34 opt*=a[x]; 35 if(opt==-1)r=mid-1; 36 if(opt==1)l=mid+1; 37 } 38 return 0; 39 }
E. Border
题意:
你有n个数,每个数可以用无限次,求在模k意义下你能表示出哪些数
n,k<=100000
题解:
有一个结论是能被这些数模k意义下线性表示的最小数是gcd(k,a_1,a_2,……,a_n)
然后是这个数的倍数都可以
#include<bits/stdc++.h> #define maxn 100005 using namespace std; int n,k; int a[maxn]; int gcd(int a,int b) { if(!b)return a; return gcd(b,a%b); } int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;++i) { scanf("%d",&a[i]); } int t=k; for(int i=1;i<=n;++i)t=gcd(a[i],t); int tot=0; for(int i=1;i<=k;++i) { if(i%t==0)tot++; } printf("%d ",tot); if(k%t==0)printf("0 "); for(int i=1;i<k;++i) { if(i%t==0)printf("%d ",i%k); } return 0; }
F. Mars rover
题意:
不好描述,直接英文看题面吧 http://codeforces.com/contest/1011/problem/F
题解:
考虑每次改动只影响一条链,所以我们可以预处理出来每个点状态为0/1,其他不变,朝上跳会变成什么数
倍增搞一搞就行了
1 #include<bits/stdc++.h> 2 #define maxn 1000005 3 using namespace std; 4 int n; 5 int tp[maxn],fa[maxn],son[maxn][2],val[maxn]; 6 void dfs(int u) 7 { 8 if(tp[u]==1)return; 9 if(son[u][0])dfs(son[u][0]); 10 if(son[u][1])dfs(son[u][1]); 11 if(tp[u]==2)val[u]=val[son[u][0]]^1; 12 if(tp[u]==3)val[u]=val[son[u][0]]&val[son[u][1]]; 13 if(tp[u]==4)val[u]=val[son[u][0]]|val[son[u][1]]; 14 if(tp[u]==5)val[u]=val[son[u][0]]^val[son[u][1]]; 15 } 16 int anc[maxn][22]; 17 bool Ans[2][maxn][22]; 18 inline int get(int u,int v,int x) 19 { 20 if(tp[u]==2)return x^1; 21 int ls=son[u][0],rs=son[u][1]; 22 if(rs==v)swap(ls,rs); 23 if(tp[u]==3)return x&val[rs]; 24 if(tp[u]==4)return x|val[rs]; 25 if(tp[u]==5)return x^val[rs]; 26 } 27 void init() 28 { 29 for(int i=2;i<=n;++i) 30 { 31 anc[i][0]=fa[i]; 32 Ans[0][i][0]=get(fa[i],i,0); 33 Ans[1][i][0]=get(fa[i],i,1); 34 } 35 for(int j=1;j<=20;++j) 36 { 37 for(int i=1;i<=n;++i) 38 { 39 anc[i][j]=anc[anc[i][j-1]][j-1]; 40 Ans[0][i][j]=Ans[Ans[0][i][j-1]][anc[i][j-1]][j-1]; 41 Ans[1][i][j]=Ans[Ans[1][i][j-1]][anc[i][j-1]][j-1]; 42 } 43 } 44 } 45 int query(int u) 46 { 47 int ans=val[u]^1; 48 for(int i=20;i>=0;--i)if(anc[u][i]) 49 { 50 ans=Ans[ans][u][i]; 51 u=anc[u][i]; 52 } 53 return ans; 54 } 55 int main() 56 { 57 scanf("%d",&n); 58 for(int i=1;i<=n;++i) 59 { 60 char opt[5]; 61 scanf("%s",opt); 62 int x,y; 63 if(opt[0]==‘I‘) 64 { 65 tp[i]=1; 66 scanf("%d",&x); 67 val[i]=x; 68 } 69 if(opt[0]==‘N‘) 70 { 71 tp[i]=2; 72 scanf("%d",&x); 73 son[i][0]=x;fa[x]=i; 74 } 75 if(opt[0]==‘A‘) 76 { 77 tp[i]=3; 78 scanf("%d%d",&x,&y); 79 son[i][0]=x;son[i][1]=y;fa[x]=fa[y]=i; 80 } 81 if(opt[0]==‘O‘) 82 { 83 tp[i]=4; 84 scanf("%d%d",&x,&y); 85 son[i][0]=x;son[i][1]=y;fa[x]=fa[y]=i; 86 } 87 if(opt[0]==‘X‘) 88 { 89 tp[i]=5; 90 scanf("%d%d",&x,&y); 91 son[i][0]=x;son[i][1]=y;fa[x]=fa[y]=i; 92 } 93 } 94 dfs(1); 95 init(); 96 for(int i=1;i<=n;++i)if(tp[i]==1)printf("%d",query(i)); 97 puts(""); 98 return 0; 99 }
以上是关于codeforces round #499(div2) 做题记录的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #499 (Div. 2) - 赛后补题
Codeforces Round #499 (Div. 2)D. Rocket
Codeforces Round #705 (Div. 2)