http://codeforces.com/contest/1341/problem/C

生成一个[1,n]的排列a[ ],对于第i步,为数字i选择一个位置,位置选择规则如下:

1.定义一个 r[j] 数组,代表位置: j≤r[j]≤n,   r[j]取最小值但不能取a[]中已经生成数字的位置,如果没有位置可以取了,则r[j]的值未定义。

2.定义一个 count[t]数组,count[t]=r[]数组中 t 的个数

3.在还没有被占用的位置中,选择count[t]中值最大的位置,如果值最大的位置有多个,可随机选择位置。

输入给出一个[1,n]的排列,问可以通过上面的方法生成吗?

题意很绕,,,,看案例,, 简直就是题意杀,看懂题意后想着直接根据题意写模拟,但水平有限,模不出来,抠脑壳,然后就gg了,掉分掉分,一朝回到解放前,大哭😭😭😭,,,结束后想了很久,写不出来,然后就手动模拟了一遍案例,然后 嗯?模着模着发现了规律,所以不会的时候多模拟模拟,说不定有你没发现的规律呢,然后就解了,题解真难写啊,其实是题意难写,也没有题解,只有个规律,自己推推就出来了,实在写不出来推规律的过程,头疼,这可能就是英语+语文菜鸡吧,,

案例:

生成的数组必须满足以下规律:

#include <bits/stdc++.h>
using namespace std;
const int MAXN=5e5+5;
const int mod=1e9+7;
typedef long long ll;
const int inf=0x3f3f3f3f;
const long long INF=0x3f3f3f3f3f3f3f3f;
int a[MAXN];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        int minn=a[1];//记录递增的第一个数,后面开始递增的第一个数必须比这个数小
        int f=0;
        for(int i=2;i<=n;i++)
        {
            while(a[i]==a[i-1]+1&&i<=n)i++;
            
            if(i>n)continue;  //多组案例,越界后可能影响答案
            
            if(a[i]>minn)
            {
                f=1;
                break;
            }
            else minn=a[i];
        }
        if(f)printf("No\n");
        else printf("Yes\n");
    }
    return 0;
}
View Code

 

posted on 2020-04-24 19:33  MZRONG  阅读(222)  评论(0编辑  收藏  举报