贪心没过,不知道那里错了,求证伪
查看原帖
贪心没过,不知道那里错了,求证伪
606710
dzy5551012楼主2022/8/8 16:22

写了个贪心,但是错了。 基本思路是从小往大填,如果这个位置填过了就尝试左右(先左一后右一再左二右二,依次类推)不知道如何证伪

#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;
}
2022/8/8 16:22
加载中...