写了个贪心,但是错了。 基本思路是从小往大填,如果这个位置填过了就尝试左右(先左一后右一再左二右二,依次类推)不知道如何证伪
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
int q;
int vis[450];
int pi[250];//偏转量
int n;
priority_queue<int,vector<int>,greater<int>>qu;
void solve(){
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(int i=1;i<=n;++i){
pi[i]=1;
}
ll ans =0;
int ci;
for(int i=1;i<=n;++i){
scanf("%d",&ci);
qu.push(ci);
}
//cout<<"ok input"<<endl;
for(;!qu.empty();){
ci=qu.top();
qu.pop();
//cout<<"ci "<<ci<<endl;
if(!vis[ci]){
vis[ci]=1;
}
else{
//cout<<"else"<<endl;
//bool t=(ci-pi[ci]>0) && !vis[ci-pi[ci]];
//cout<<"tiaojian2 "<< t<<endl;
if((ci-pi[ci]>0) && !vis[ci-pi[ci]]){
//cout<<"else2"<<endl;
vis[ci-pi[ci]]=1;
ans+=pi[ci];
}
else if(!vis[ci+pi[ci]]){
//cout<<"else1"<<endl;
vis[ci+pi[ci]]=1;
ans+=pi[ci];
}
else {
//cout<<"else3"<<endl;
++pi[ci];
for(;vis[ci+pi[ci]]&&(ci-pi[ci]<0 ||vis[ci-pi[ci]]);){
++pi[ci];
}
//cout<<"ok1 "<<pi[ci]<<endl;
//if()
if((ci-pi[ci]>0) && !vis[ci-pi[ci]]){
vis[ci-pi[ci]]=1;
ans+=pi[ci];
}
else if(!vis[ci+pi[ci]]){
vis[ci+pi[ci]]=1;
ans+=pi[ci];
}
//cout<<"ok2"<<endl;
}
}
}
cout<<ans<<endl;
}
int main(){
scanf("%d",&q);
for(int i=1;i<=q;++i){
solve();
}
return 0;
}