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