[codeforces 1372C]Omkar and Baseball

题目: 1372C
题意:给定一个从1~n的顺序不定的数组,定义一种排序操作:区间[L,R],操作后里面的所有数都不在原来的位置上。求几次操作可以把数组变成1,2,3,…n的顺序。
思路:
没有经过严格的论证,但是造了几个数据发现如下规律:

1.排序操作最多进行两次。
把所有在正确位置的数记为1,不正确位置的数记为0;
比如52341 (01110)
如果对于区间[1,5]排序,所有对1的操作都必须把1变成0;所有对0的操作一定可以把0变成1;
无论是怎么样的乱序,都可以通过一次操作变成全部0;
所以52341 -> 43512 (00000) (答案不唯一)
然后00000全部翻成11111,也就是12345答案。

2.位于首、尾的1可以忽略。比如12435(11001),那么12和5的位置我们就不要动了,直接对[3,4]进行操作。

我们可以在输入数据的时候就把位置正确的记为1,不正确的记为0.
然后,直接对数组进行unique去重。将得到以下几种情况。
全部为1的情况下*(len == 1 && a[0] == 1)*,需要进行0次操作。
000001111或者111000或者1110001111,我们可以忽略首尾的1,将他们视作0000,这种情况下需要1次操作。
len>=2的情况下,进行2次操作。

#include
using namespace std;
const int MAXN = 2e5;
int a[MAXN];
int b[MAXN];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i = 0; i < n; i++){
            scanf("%d",&a[i]);
            if(a[i] == i+1)
            {
                b[i] = 1;
            }else
                b[i] = 0;
        }
        int len = unique(b,b+n) - b;
        if(len == 1&&b[0]==1)
            cout << 0 << endl;
        else if(len == 2||(len==1&&b[0]==0))
            cout << 1 << endl;
        else if(len == 3)
        {
            if(b[0]==0)
                cout << 2 << endl;
            else
                cout << 1 << endl;
        }else
            cout << 2 << endl;
    }
    return 0;
}

代码写的有点乱。
这大概是第一次做出DIV2的C题,虽然分数只有1500.
结果没有计算rating,失去了一个上分机会……

你可能感兴趣的:(题解)