Moving stones---------------------------思維(模擬+優先隊列)

在這裏插入圖片描述
在這裏插入圖片描述
題意:
有n堆石頭,現在選擇d第i堆石頭,需要從剩下來的n-1堆中各選出1個,放到第i堆。(沒有的不取)
問最終是否能使得n堆石頭的數量都一樣

解析:
最容易看出來的就是如果n堆石頭之和不能均分,那麼肯定是輸出NO
爲了達到目的我們肯定是讓小的+ 大的-
所以我們把這些數放到小根堆中
如何處理第i堆+(n-1) 其餘堆-1 ??
可以O(1)的時間的複雜度做到。
我們只要用了計數器k,然後每次取出來的第一個都+n,等下次取出來的時候我們就減去k即可

如果我們-k得到的數正好等於平均數 那麼輸出Yes
如果我們-k<0 的話,只能輸出No

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+1000;
typedef long long ll;
typedef pair<ll,ll> PII;
priority_queue<ll,vector<ll>,greater<ll > > q;
ll a[N];
ll t,n;
inline int read() {
    int x=0;
    bool t=false;
    char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
int main()
{
	t=read();
	while(t--)
	{
		n=read();
		ll sum=0; 
		while(!q.empty()) q.pop();
		for(int i=1;i<=n;i++)
		{
			a[i]=read();
			sum+=a[i];
			q.push(a[i]);
		}
		if(sum%n!=0) cout<<"No"<<endl;
		else
		{
			ll avg = sum/n;
			ll k=0;
			int f=0;
			for(int i=1;i<=10000;i++)
			{
				if(q.top()-k==avg) {f=1;break;}
				if(q.top()-k<0)  {f=0;break;}
				ll tmp=q.top()+n;
				q.pop();
				k++;
				q.push(tmp);
				
			}
			if(f==1) cout<<"Yes"<<endl;
			else cout<<"No"<<endl;
		}
		
	}
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章