VJ链接
题意:
给出长度为n和m的两个集合,分别表示 一些待排序的数 和 这些数可以执行交换操作的位置 。
若m=2,设集合二为:3,6 。则集合一第 3 位第 4 位可交换,第 6 位和第 7 位可执行交换。
问,只经过过规定可执行的交换,能否把这串数从小到大排序完成
思路:
需要执行交换的情况一定是前面的数大于后面的数。对集合一中的任意两个数x,y,如果x>y 且x到y之间的位置存在不能执行交换的位置,则集合一定不能排序完成。
用反证法,找不能交换的情况。找到了就是No,否则,yes,说白了就是三层循环。
#include<stdio.h>
#include<string.h>
int a[110],b[110];
int t,n,m,x,flag;
int main()
{
scanf("%d",&t);
while(t--)
{
memset(b,0,sizeof(b));
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
for(int i=0; i<m; i++)
{
scanf("%d",&x);
b[x-1]=1; //下标转换
}
for(int i=0; i<n; i++)
{
flag=0;
for(int j=i+1; j<n; j++) //双层循环,对比所有情况
{
if(a[i]>a[j]) //找需要交换的位置
{
for(int k=i; k<j; k++) //若i到j存在不能执行交换的位置,跳出
if(!b[k])
{
flag=1;break;
}
}
if(flag) break;
}
if(flag) break;
}
if(flag)
printf("NO\n");
else
printf("YES\n");
}
return 0;
}