Codeforces Global Round 12 D. Rating Compression(思维,尺取)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Global Round 12 D. Rating Compression(思维,尺取)相关的知识,希望对你有一定的参考价值。

LINK

先特判掉 k = 1 k=1 k=1 k = n k=n k=n的情况(下面说的任意 k k k都不包括 k = 1 k=1 k=1 k = n k=n k=n)

考虑任何一个排列的最小值都是 1 1 1

如果 1 1 1出现在数组的中间位置,显然不合法,因为对于任何的 k k k必然会尺取到两次 1 1 1

由此可得, 1 1 1必然出现在开头或结尾,且不能同时出现

那我们考虑判断 k = n − 1 k=n-1 k=n1是否合法

不妨设开头为 1 1 1,那么现在相当于判断 [ 2 , n ] [2,n] [2,n]的最小值是否为 2 2 2,是的话就合法

如果此时不合法,那更小的 k k k也不可能合法,因为缺失了数字 2 2 2

如果合法,考虑判断 k = n − 2 k=n-2 k=n2是否合法

刚才已经知道 [ 1 , n − 2 ] [1,n-2] [1,n2]的最小值为 1 1 1

问题转化为 [ 2 , n ] [2,n] [2,n]的数组 a a a k k k压缩后是否可能是一个从 2 2 2开始的排列

很明显是一个递归的问题,再次判断首尾是否是 2 2 2,再判断中间是否为 3 3 3

以此类推,一直尺取把 k k k缩小即可

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
int t[maxn],ans[maxn],a[maxn],n;
int main()
{
	int T; cin >> T;
	while( T-- )
	{
		cin >> n;
		for(int i=1;i<=n;i++)	cin >> a[i],t[a[i]]++;
		if( t[1] )	ans[n] = 1;
		ans[1] = 1;
		for(int i=1;i<=n;i++)
			if( t[i]!=1 )	ans[1] = 0;
		int l = 1, r = n;
		for(int i=1;i<n;i++)
		{
			if( !t[i] )	break;
			if( t[i]>1 )	break;//有多于1个i,必然被尺取到两次 
			if( a[l]==i && t[i+1] )	l++, ans[n-i] = 1;
			else if( a[r]==i && t[i+1] )	r--, ans[n-i] = 1;//满足首位是i,中间部分最小值是i+1 
			else	break;
		}
		for(int i=1;i<=n;i++)	cout << ans[i];
		cout << endl;
		for(int i=1;i<=n;i++)	ans[i] = t[i] = 0;
	}
	return 0;
}

以上是关于Codeforces Global Round 12 D. Rating Compression(思维,尺取)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Global Round 1

Codeforces Global Round 1

Codeforces Global Round 1

Codeforces Global Round 1

Codeforces Global Round 19

Codeforces Global Round 1 AParity