题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5821
题意:
给定一个初始态的序列: 1 1 2 2 0 以及一个终态的序列:2 2 1 1 0
进行m次区间操作,问是否能将初始态序列转变为终态的序列。
首先可以对初始态序列每个位置的每一个值对关于终态的位置进行标识。
比如序列1 1 2 2 0可以标识为3 4 1 2 5。(即每个元素对应终态的位置)
则问题就转换为将序列3 4 1 2 5转换为终态1 2 3 4 5。
那么对于每次的区间操作,就是将该区间的数进行排序。
再看m次区间排序之后该数列整体能否成为一个有序的数列。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1100;
int t, n, m;
struct node{
int val, key;
bool operator < (const node &A) const{
return key < A.key;
}
} a[maxn];
int b[maxn], vis[maxn];
bool check(){
for(int i = 1; i <= n; i++){
if(vis[b[i]]){
vis[b[i]]--;
}else{
return false;
}
}
return true;
}
int main(){
cin >> t;
while(t--){
scanf("%d%d", &n, &m);
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i++){
scanf("%d", &a[i].val);
a[i].key = 0;
vis[a[i].val]++;
}
for(int i = 1; i <= n; i++){
scanf("%d", &b[i]);
for(int j = 1; j <= n; j++){
if(b[i] == a[j].val && !a[j].key){
a[j].key = i;
break;
}
}
}
while(m--){
int l, r;
scanf("%d%d", &l, &r);
sort(a+l, a+r+1);
}
if(!check()){
puts("No");
continue;
}
bool flag = 0;
for(int i = 1; i <= n; i++)
if(a[i].val != b[i]){
flag = 1;
break;
}
if(flag){
puts("No");
}else{
puts("Yes");
}
}
return 0;
}
本文探讨了一个序列转换问题,通过一系列区间操作尝试将一个初始序列转换为目标序列。文章详细介绍了如何使用排序和标记的方法来验证序列转换的可能性。
585

被折叠的 条评论
为什么被折叠?



