比赛链接
https://codeforces.com/contest/1011
题解
A. Stages
题目大意
给定一个长度为 n n 的字符串,找出 k k 个在中出现的字母,使得这 k k 个字母在字母表中不相邻。如果不存在输出,如果存在输出最小的“重量”之和,其中a的重量为1,b的重量是2……
1≤k≤n≤50 1 ≤ k ≤ n ≤ 50
题解
直接按照题意模拟即可。
B. Planning The Expedition
题目大意
总共有 m m 份食物,每份食物都有一个种类,现在有 n n 个人,每个人每天只能吃一种食物,不同的人可以吃不同的食物。问这些食物最多能维持多少天。
题解
二分答案,二分出来答案就很好判定了。
C. Fly
题目大意
n n 个行星,每个行星都有一个启动系数和降落系数 bi b i ,代表起飞/降落时一单位燃料能够推动的飞船+燃料的重量。现在有一个飞船,重量为 m m ,要从一号行星起飞到二号行星降落,再从二号行星起飞到三号行星降落,……,一直到号行星降落,最后从 n n 号行星起飞到一号行星降落。求飞船起飞时需要携带的最小燃料。
题解
倒着推,如果起飞/降落系数为
k
k
,起飞/降落后的重量为,需要携带的燃料为
x
x
,那么
按照逆序求需要携带的燃料。
D. Rocket
题目大意
交互题,要你猜一个数字,大于你猜的数字返回1,小于则返回-1,等于返回0,有可能会出错,出错的状态是一个循环。或者说,若返回的结果为 k k ,真实的结果为,当前是第 i i 次猜测,出错状态的长度为,则 k=pi mod n×v k = p i m o d n × v 。最多猜测60次。
n≤30 n ≤ 30 ,数字大小 ≤109 ≤ 10 9
题解
前 n n 次都猜,如果得到 0 0 那么就返回,否则得到的结果一定是,如果没有得到 1 1 说明出错了。通过这种方法能得到,最后二分查找 [n+1,109] [ n + 1 , 10 9 ] ,有了 p p 很容易得到正确的结果。
E. Border
题目大意
给出个值 v1,v2,⋯,vn v 1 , v 2 , ⋯ , v n ,判断这些值通过加法能够凑出模 k k 意义下最后一位为多少的值,可以重复使用同一个值。
题解
如果有
m
m
个值能被凑出来,设
x=gcd(a1,a2,⋯,am)
x
=
gcd
(
a
1
,
a
2
,
⋯
,
a
m
)
,那么一定有:
考虑 g=gcd(v1,v2,⋯,vn) g = gcd ( v 1 , v 2 , ⋯ , v n ) ,显然上面式子的 x=g x = g 。那么答案就可以枚举得到了。
F. Mars rover
题目大意
给一棵 n n 个节点的数,每个节点有以下属性:
IN:0个儿子,值为本身的值;
AND:2个儿子,值为左儿子的值and右儿子的值;
XOR:2个儿子,值为左儿子的值xor右儿子的值;
OR:2个儿子,值为左儿子的值or右儿子的值;
NOT:1个儿子,值为not儿子的值。
求改变一个IN节点对根节点值的影响,注意一次只有一个IN节点的值被改变了。
题解
首先dfs一边求出每个节点的值,然后再一次dfs,考虑如果当前节点的值改变能让根节点的值改变,它的儿子应该怎样改变才能让根节点的值改变。
AND:只要另一个儿子值为1,这个儿子改变了就会使这个节点的值发生改变。
XOR:无论如何,一个儿子改变了这个点的值就会改变。
OR:只要另一个儿子的值为0,这个儿子改变了就会使这个点的值发生改变。
NOT:儿子改变了这个点的值就会改变。
dfs一边即可。
代码
A. Stages
#include <cstdio>
const int maxn=50;
int n,k,f[30];
char s[maxn+3];
int main()
{
scanf("%d%d%s",&n,&k,s+1);
for(int i=1; i<=n; ++i)
{
f[s[i]-'a'+1]=1;
}
int ans=0,tot=0;
for(int i=1; i<=26; ++i)
{
if(f[i])
{
++tot;
ans+=i;
f[i+1]=0;
if(tot==k)
{
break;
}
}
}
if(tot<k)
{
puts("-1");
}
else
{
printf("%d\n",ans);
}
return 0;
}
B. Planning The Expedition
#include <cstdio>
const int maxn=100;
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int n,m,a[maxn+10],f[maxn+10];
int check(int x)
{
int sum=0;
for(int i=1; i<=100; ++i)
{
sum+=f[i]/x;
}
if(sum>=n)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
n=read();
m=read();
for(int i=1; i<=m; ++i)
{
a[i]=read();
++f[a[i]];
}
int l=1,r=m;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))
{
l=mid+1;
}
else
{
r=mid-1;
}
}
printf("%d\n",l-1);
return 0;
}
C. Fly
#include <cstdio>
const int maxn=1000;
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int n,m,a[maxn+10],b[maxn+10];
double w;
int main()
{
n=read();
m=read();
for(int i=1; i<=n; ++i)
{
a[i]=read();
}
for(int i=1; i<=n; ++i)
{
b[i]=read();
}
for(int i=1; i<=n; ++i)
{
if((a[i]<=1)||(b[i]<=1))
{
puts("-1");
return 0;
}
}
w=m+(1.0*m)/(b[1]-1);
for(int i=n; i>=2; --i)
{
w+=w/(a[i]-1);
w+=w/(b[i]-1);
}
w+=w/(a[1]-1);
printf("%.7lf\n",w-m);
return 0;
}
D. Rocket
#include <cstdio>
const int maxn=30;
int n,m,p[maxn+3];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=m; ++i)
{
printf("%d\n",i);
fflush(stdout);
scanf("%d",&p[i]);
if(p[i]==0)
{
return 0;
}
}
int l=m+1,r=n,i=1;
while(l<=r)
{
int mid=(l+r)>>1;
printf("%d\n",mid);
fflush(stdout);
int x;
scanf("%d",&x);
x*=p[i];
if(x==0)
{
return 0;
}
else if(x==1)
{
l=mid+1;
}
else
{
r=mid-1;
}
++i;
if(i>m)
{
i=1;
}
}
return 0;
}
E. Border
#include <cstdio>
const int maxn=100000;
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int ans,n,k;
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
n=read();
k=read();
for(int i=1; i<=n; ++i)
{
int a=read();
ans=gcd(gcd(a,k),ans);
}
printf("%d\n",k/ans);
for(int i=0; i<k; i+=ans)
{
printf("%d ",i);
}
puts("");
return 0;
}
F. Mars rover
#include <cstdio>
const int maxn=1000000;
struct node
{
int op,val,id;
node *son[2];
};
node t[maxn+10],*root;
int n,cnt,ans[maxn+10];
int getval(node *u)
{
if(u->op==0)
{
return u->val;
}
else if(u->op==1)
{
return u->val=(getval(u->son[0])&getval(u->son[1]));
}
else if(u->op==2)
{
return u->val=(getval(u->son[0])^getval(u->son[1]));
}
else if(u->op==3)
{
return u->val=(getval(u->son[0])|getval(u->son[1]));
}
else
{
return u->val=(!getval(u->son[0]));
}
}
int getans(node* u)
{
if(u->op==0)
{
ans[u->id]=!ans[u->id];
return 0;
}
else if(u->op==1)
{
if(u->son[0]->val==1)
{
getans(u->son[1]);
}
if(u->son[1]->val==1)
{
getans(u->son[0]);
}
}
else if(u->op==2)
{
getans(u->son[0]);
getans(u->son[1]);
}
else if(u->op==3)
{
if(u->son[0]->val==0)
{
getans(u->son[1]);
}
if(u->son[1]->val==0)
{
getans(u->son[0]);
}
}
else if(u->op==4)
{
getans(u->son[0]);
}
return 0;
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; ++i)
{
char op[10];
int l,r;
scanf("%s",op);
if(op[0]=='I')
{
scanf("%d",&l);
t[i].op=0;
t[i].val=l;
t[i].id=++cnt;
}
else if(op[0]=='A')
{
scanf("%d%d",&l,&r);
t[i].op=1;
t[i].son[0]=&t[l];
t[i].son[1]=&t[r];
}
else if(op[0]=='X')
{
scanf("%d%d",&l,&r);
t[i].op=2;
t[i].son[0]=&t[l];
t[i].son[1]=&t[r];
}
else if(op[0]=='O')
{
scanf("%d%d",&l,&r);
t[i].op=3;
t[i].son[0]=&t[l];
t[i].son[1]=&t[r];
}
else if(op[0]=='N')
{
scanf("%d",&l);
t[i].op=4;
t[i].son[0]=&t[l];
}
}
root=&t[1];
getval(root);
for(int i=1; i<=cnt; ++i)
{
ans[i]=root->val;
}
getans(root);
for(int i=1; i<=cnt; ++i)
{
printf("%d",ans[i]);
}
puts("");
return 0;
}