比赛链接

https://codeforces.com/contest/1011

题解

A. Stages

题目大意

给定一个长度为n的字符串S,找出k个在S中出现的字母,使得这k个字母在字母表中不相邻。如果不存在输出1,如果存在输出最小的“重量”之和,其中a的重量为1,b的重量是2……

1kn50

题解

直接按照题意模拟即可。

B. Planning The Expedition

题目大意

总共有m份食物,每份食物都有一个种类ai,现在有n个人,每个人每天只能吃一种食物,不同的人可以吃不同的食物。问这些食物最多能维持多少天。

1n,m,ai100

题解

二分答案,二分出来答案就很好判定了。

C. Fly

题目大意

n个行星,每个行星都有一个启动系数ai和降落系数bi,代表起飞/降落时一单位燃料能够推动的飞船+燃料的重量。现在有一个飞船,重量为m,要从一号行星起飞到二号行星降落,再从二号行星起飞到三号行星降落,……,一直到n号行星降落,最后从n号行星起飞到一号行星降落。求飞船起飞时需要携带的最小燃料。

1n,m,ai,bi1000

题解

倒着推,如果起飞/降落系数为k,起飞/降落后的重量为b,需要携带的燃料为x,那么

x=bk1

按照逆序求需要携带的燃料。

D. Rocket

题目大意

交互题,要你猜一个数字,大于你猜的数字返回1,小于则返回-1,等于返回0,有可能会出错,出错的状态是一个循环。或者说,若返回的结果为k,真实的结果为v,当前是第i次猜测,出错状态的长度为n,则k=pi mod n×v。最多猜测60次。

n30,数字大小109

题解

n次都猜i,如果得到0那么就返回,否则得到的结果一定是1,如果没有得到1说明出错了。通过这种方法能得到p,最后二分查找[n+1,109],有了p很容易得到正确的结果。

E. Border

题目大意

给出n个值v1,v2,,vn,判断这些值通过加法能够凑出模k意义下最后一位为多少的值,可以重复使用同一个值。

n,k105,vi109

题解

如果有m个值a1,a2,,am能被凑出来,设x=gcd(a1,a2,,am),那么一定有:

a1=0,a2=x,a3=2x,,am=(m1)x,x|d

考虑g=gcd(v1,v2,,vn),显然上面式子的x=g。那么答案就可以枚举得到了。

F. Mars rover

题目大意

给一棵n个节点的数,每个节点有以下属性:

IN:0个儿子,值为本身的值;

AND:2个儿子,值为左儿子的值and右儿子的值;

XOR:2个儿子,值为左儿子的值xor右儿子的值;

OR:2个儿子,值为左儿子的值or右儿子的值;

NOT:1个儿子,值为not儿子的值。

求改变一个IN节点对根节点值的影响,注意一次只有一个IN节点的值被改变了。

n106

题解

首先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;
}