题意:
给你n个盒子,每个盒子里可能有球或者没有,告诉你球的颜色,没有就是0,m次操作,每次操作可以把一个区间里的球都拿出来,重新放进去,问你m次操作后能不能到达目标状态 每个盒子最多放一个球
题解:
这是一道贪心
假如对于这样一排盒子
1 0 0 1 1 3 2 1
目标状态是 3 2 0 0 1 1 1 1
我们将初始状态颜色为1的球拿出来,标号为 a1 a2 a3 a4 ,
易知如果能到达目标状态,一定有一种方法使得目标状态变为 3 2 0 0 a1 a2 a3 a4
所以做法是将末状态的所有球拿出来标号以得知初始的标号(没有球就将他当成颜色为0的球拿出来),记录每种颜色有哪些序号,然后按初始同颜色球的排列顺序给这个球标上这个颜色的序号,每次操作对给定的区间排序,操作完判断一下就行了
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<ctime>
#include<ctime>
#include<vector>
#include<string>
#include<bitset>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 1010;
int a[maxn],b[maxn];
int id[maxn][maxn],pos[maxn];
int n,m;
int main()
{
int t,l,r;
scanf("%d",&t);
while( t-- )
{
scanf("%d%d",&n,&m);
for( int i=1;i<=n;i++ ) scanf("%d",&a[i]);
for( int i=1;i<=n;i++ )
{
scanf("%d",&b[i]);
id[b[i]][0] = 0;
pos[b[i]] = 0;
}
int k=0;
for( int i=1;i<=n;i++ )
{
k++;
id[b[i]][++id[b[i]][0]] = k;
b[i] = k;
}
for( int i=1;i<=n;i++ )
{
k = ++pos[a[i]];
a[i] = id[a[i]][k];
}
while( m-- )
{
scanf("%d%d",&l,&r);
sort( a+l,a+r+1 );
}
bool flag = true;
for( int i=1;i<=n;i++ )
if( b[i] )
{
if( a[i] != b[i] )
{
flag = false;
break;
}
}
if( flag == true ) printf("Yes\n");
else printf("No\n");
}
return 0;
}