codeforces 288,289(Round #177)题解

来源:互联网 发布:订单源码 编辑:程序博客网 时间:2024/04/30 22:37

2A:水题

2B:很容易想到排个序,取中位数即可。将所有数尽量变成中位数即可

1A:在后面还可以完成要求不同字母的个数的前提下,前面尽量排ab,然后再排新字母

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>int main(){      int i,n,k;      scanf("%d%d",&n,&k);      if(k>n || (k==1 && n>1)) printf("-1");      else       {        for(i=0;i<n;++i)        {          if(n-i-(k-2)<=0)  printf("%c",'a'+i+k-n);           else printf("%c",'a'+(i&1));        }      }      return 0;}

1B:显然,第二个条件的答案是(n-k)^(n-k),前面的比较麻烦。我们可以这样想,总共k^k种,减去可能的自环(2~k的自环)(k-1)*k^(k-1) is k^(k-1),即为k^(k-1)

ans=k^(k-1)*(n-k)^(n-k)

1C:YY一下,想要答案最大,一定要所有异或都不浪费,即要0,1互补,我们从最大的数找起,找到与其互补的数即可

#include<cstdio>  //ans=(0+n)*(n+1)/2*2=n*(n+1) #include<iostream>#include<algorithm>#include<cstring>const int N=1000005;int a[N];int main(){      int i,j,n;      scanf("%d",&n);      int t=n;      while(t>0)      {        for(i=1;i<t;i=(i<<1)+1);        for(j=t;j>=i-t;--j) a[j]=i-j;        t=i-t-1;      }      printf("%I64d\n",(long long )n*(n+1));      for(i=0;i<=n;++i) printf("%d ",a[i]);      return 0;}

1D:个人感觉同样是正面想不太好想的题,反面考虑,把总情况减去相交的即可。相交的分为2种,一种是内部相交,一种是一内一外。上代码:

#include<cstdio>  #include<iostream>#include<vector>#include<algorithm>#include<cstring>using namespace std;const int N=80005;long long ans=0ll;int n,a[N];vector<int> g[N];void dfs(int u,int f){      a[u]=1;      long long in=0ll;      for(int i=0;i<g[u].size();++i)      {        int v=g[u][i];        if(v==f) continue;        dfs(v,u);        in+=(long long)a[u]*a[v];        a[u]+=a[v];      }      ans-=in*(in+(long long)2*a[u]*(n-a[u]));}int main(){      scanf("%d",&n);      int i;      int x,y;      for(i=1;i<n;++i)      {        scanf("%d%d",&x,&y);        g[x].push_back(y);        g[y].push_back(x);      }      ans=(long long)n*(n-1)/2; //c[n][2]      ans*=ans;      dfs(1,0);      printf("%I64d",ans);      return 0;}