牛客多校-Jellyfish and its dream-(差分)

J

题意:
就是给你一个数组,下标从0开始,每个点的权值为0,1,2。如果(va[i]+1)%3 = va[i+1]。那么va[i] = (va[i]+1)%3。当然i==n-1的时候,下一个就是va[0]。问你是否可以把这个数组变成全部相同的数。

思考:

  1. 这种让一个数组变成相同的数,或者变成某一个数,大部分情况都是求出来差分数组,让差分数组都等于0。
  2. 这个题目并不是让你每次修改一段区间之类的,而是修改某一个数,但是这些数的范围都很小。根据题意可知,就是(0,1)->(1,1),(1,2)->(2,2),(2,0)->(0,0)。只有这三种变化。但是这样也不好看呀,既然知道是处理差分数组,那么把这集中操作转化成差分数组里面的变化就是(0,1)->(1,0),(1,1)->(2,0),(2,-2)->(0,0)。对于(2,-2)->(0,0)其实就是(2,1)->(0,0)。因为(-2+3)%3 = 1。我们都转化成正的。
  3. 但是到这里该怎么操作呢?发现(0,1)->(1,0)那么1的位置可以随便走,(2,1)->(0,0),所以尽量让(2,1)匹配,如果没有2了,那么就用(1,1)->(2,0),构造出2。所以发现只要差分数组中1的个数>=2的个数就可以。

代码:

#include
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
		
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e6+10,M = 2010;

int T,n,m,k;
int va[N];
int sum[N];

signed main()
{
	IOS;
	cin>>T;
	while(T--)
	{
		cin>>n;
		for(int i=0;i<n;i++) cin>>va[i];
		for(int i=0;i<n;i++) sum[i] = (va[(i+1)%n]-va[i]+3)%3;
		int a = 0,b = 0;
		for(int i=0;i<n;i++)
		{
			a += (sum[i]==1);
			b += (sum[i]==2);
		}
		a>=b?cout<<"YES\n":cout<<"NO\n";
	}
	return 0;
}

总结:
多多思考。

你可能感兴趣的:(思维,算法,c++,图论)