C. Array Destruction
题意:
给一个长度为2n的数列,每次可选择和为x的两个数删掉,然后x变为删掉的两个数中较大的数。初始的x可自由设置。
问是否能把数列删完
题解:
首先要删完数列,最大的数肯定是最先删掉。
看到n比较小,可以暴力枚举和最大的数一起删掉的数。
然后模拟就好了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int cnt[maxn],a[2005];
int main()
{
int t,n,m;
int flag,fl;
int last,x;
scanf("%d",&t);
while(t--){
flag=0;
scanf("%d",&m);
n=(m<<1);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),cnt[a[i]]++;
sort(a+1,a+1+n);
for(int j=1;j<n;j++){
x=a[j]+a[n];
last=a[n];
cnt[a[j]]--; cnt[a[n]]--;
for(int i=n-1;i>0;i--){
if(cnt[a[i]]==0)continue;
else{
cnt[a[i]]--;
if(cnt[last-a[i]]>0){
cnt[last-a[i]]--;
last=a[i];
}
else{
cnt[a[i]]++;
break;
}
}
}
fl=1;
for(int i=1;i<=n;i++){
if(cnt[a[i]]>0){
fl=0; break;
}
}
for(int i=1;i<=n;i++)cnt[a[i]]=0;
for(int i=1;i<=n;i++)cnt[a[i]]++;
if(fl){
flag=1; break;
}
}
if(flag){
printf("YES\n%d\n",x);
printf("%d %d\n",a[n],x-a[n]);
cnt[a[n]]--; cnt[x-a[n]]--;
last=a[n];
for(int i=n-1;i>0;i--){
if(cnt[a[i]]){
printf("%d %d\n",a[i],last-a[i]);
cnt[a[i]]--; cnt[last-a[i]]--;
last=a[i];
}
}
}
else printf("NO\n");
for(int i=1;i<=n;i++)cnt[a[i]]=0;
}
return 0;
}
E. What Is It?
题意:
有如下操作:选i,j使得a[j]=i,然后交换a[j]和a[i],得到(i-j)2 的分数。
给你一个n,构造长度为n的排列,使得操作完分数最大,并给出最大分数和操作步骤。
题解:
手玩发现,如下图能得到最大分数,奇偶分情况。
然后操作的话,那长度为6的举例,操作为:
(1,4)(1,5)(6,3)(6,2)(1,6)。
#include<bits/stdc++.h>
using namespace std;
int a[100005];
long long sum;
int main()
{
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
if(n&1){
sum=0;
for(int i=n/2;i<n;i++)sum+=1ll*i*i*2;
sum-=1ll*(n/2)*(n/2);
sum-=1ll*(n-1)*(n-1);
printf("%lld\n",sum);
for(int i=(n+1)/2;i<n;i++)a[i]=i+1;
a[1]=(n+1)/2;
a[n]=n/2;
for(int i=n/2;i>1;i--)a[i]=i-1;
for(int i=1;i<=n;i++)printf("%d ",a[i]);
printf("\n%d\n",n-1);
for(int i=(n+1)/2;i<n;i++)printf("%d 1\n",i);
for(int i=n/2;i>1;i--)printf("%d %d\n",i,n);
printf("%d 1\n",n);
}
else{
sum=0;
for(int i=n/2;i<n;i++){
sum+=1ll*i*i*2;
}
sum-=1ll*(n-1)*(n-1);
printf("%lld\n",sum);
for(int i=n/2+1;i<n;i++)a[i]=i+1;
a[1]=n/2+1;
a[n]=n/2;
for(int i=n/2;i>1;i--)a[i]=i-1;
for(int i=1;i<=n;i++)printf("%d ",a[i]);
printf("\n%d\n",n-1);
for(int i=n/2+1;i<n;i++)printf("%d 1\n",i);
for(int i=n/2;i>1;i--)printf("%d %d\n",i,n);
printf("%d 1\n",n);
}
}
return 0;
}