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; }