HDU5821 Ball
【问题描述】 有 n 个盒子编号 1~n,第 i 个盒子里的球的颜色为 ai(如果 ai=0 则表示没有球)。 有 m 次操作,这 m 个操作依次进行,第 i 次操作有两个参数 li ,ri,表示你可以将区 间[li,ri]内的球全部取出后,再按你的意愿放回到区间[li,ri],同时保证一个盒子内每时 每刻最多只有一个球。 求是否存在一种方法,使得依次进行这 m 次操作后,第 i 个盒子里的球的颜色为 bi。
显然,给每个球一个标号,由于是对于每个区间任意放球,那么必定有一种情况使得放球前后球的顺序不变,那么可以采用贪心思想,对a数组进行排序,判断排序之后能否和b区间顺序一致即可。
如何排序:另外引进一个pair数组c,第一个编号代表在数组里的位置(按这个位置进行排序),第二个代表球的颜色,这样之后每个球的c数组必定互异。对于每次[l,r]区间按照在数组里的位置排序即可。(手玩就很清楚了)
#include <bits/stdc++.h>
using namespace std;
const int N=(int)1050;
int T,n,m,a[N],b[N],l,r;
bool ok;
pair<int,int> c[N];
inline int read(){
int cnt=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
while(isdigit(c)){cnt=(cnt<<3)+(cnt<<1)+(c^48);c=getchar();}
return cnt*f;
}
signed main(){
T=read();
while(T--){
n=read(),m=read();ok=0;
for(int i=1;i<=n;++i){
a[i]=read();
c[i].first=0;
c[i].second=a[i];
}
for(int i=1;i<=n;++i){
b[i]=read();
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(c[j].first==0&&c[j].second==b[i]){
c[j].first=i;
break;
}
}
}
for(int i=1;i<=m;++i){
l=read(),r=read();
sort(c+l,c+r+1);
}
for(int i=1;i<=n;++i){
if(c[i].second!=b[i]){
ok=true;
break;
}
}
if(ok) puts("No");
else puts("Yes");
}
return 0;
}