Codeforces Global Round 12 D. Rating Compression(思维,尺取)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Global Round 12 D. Rating Compression(思维,尺取)相关的知识,希望对你有一定的参考价值。
先特判掉 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=n−1是否合法
不妨设开头为 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=n−2是否合法
刚才已经知道 [ 1 , n − 2 ] [1,n-2] [1,n−2]的最小值为 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(思维,尺取)的主要内容,如果未能解决你的问题,请参考以下文章