Sorting Problem II
总提交 : 325 测试通过 : 43
比赛描述
openxxx喜欢一切有序的事物,现在有一串数字,openxxx希望对这串数字从小到大进行排序(实现非递减序)。
openxxx可以交换任意两个数字,每做一次交换,就要消耗openxxx一格体力值,openxxx希望恰好在消耗了K格体力值的情况下完成排序,请你判断是否可能存在这样的情况。
输入
多组测试数据,每组数据第一行包含一个正整数N(1<=N<=500)表示这串数字的个数,第二行包含N个正整数恰好是1~N的某一排列,相邻数字之间用一个空格隔开。第三行包含一个正整数M(1<=M<=500),接下来M行,每行包含一个非负整数K(0<=K<=50000),其含义见题目描述。
输出
每组测试数据对应M行输出,每行输出一个字符串 “YES”或者“NO”(不包括双引号),存在恰好消耗了K格体力值的情况下完成排序则输出“YES”,否则输出“NO”。
样例输入
2
2 1
2
0
1
样例输出
NO
YES
题目来源
2012南京邮电大学第四届大学生程序设计大赛(预赛)
/* Wrong Answer at Test 1
// 思路: 最少交换次数 = n-circle_count,circle_count为环的个数
#include<iostream>
#define MAX_N 501
int a[MAX_N];
bool vst[MAX_N];
int main(){
freopen("test.txt","r",stdin);
int n,i,circle_count,count,m,k;
while(scanf("%d",&n)==1){
for(i=1;i<=n;i++){
scanf("%d",a+i);
}
memset(vst,0,sizeof(vst));
circle_count = 0;
count = 0;
while(count<n){
for(i=1;i<n;i++){
if(!vst[i]){
break;
}
}
vst[i] = 1;
count++;
while(!vst[a[i]]){
i = a[i];
vst[i] = 1;
count++;
}
circle_count++;
}
// printf("circle_count = %d\n",circle_count);
scanf("%d",&m);
while(m--){
scanf("%d",&k);
if(k>=(n-circle_count) && ((k-(n-circle_count))&1)==0){
printf("YES\n");
}else{
printf("NO\n");
}
}
}
}
*/
// 思路: 最少交换次数 = n-circle_count,circle_count为环的个数
#include<iostream>
#define MAX_N 501
int a[MAX_N];
bool vst[MAX_N];
int main(){
// freopen("test.txt","r",stdin);
int n,i,circle_count,count,m,k;
while(scanf("%d",&n)==1){
for(i=1;i<=n;i++){
scanf("%d",a+i);
}
memset(vst,0,sizeof(vst));
circle_count = 0;
count = 0;
while(count<n){ // 直到所有节点被访问过为止
for(i=1;i<=n;i++){ // WA1
if(!vst[i]){
break;
}
}
vst[i] = 1; // 先找到第一个未被访问过的点
count++;
while(!vst[a[i]]){
i = a[i];
vst[i] = 1;
count++; // 访问过的节点总数
}
circle_count++;
}
// printf("circle_count = %d\n",circle_count);
scanf("%d",&m);
while(m--){
scanf("%d",&k);
if(k>=(n-circle_count) && ((k-(n-circle_count))&1)==0){ //大于最少次数,且相差偶数
printf("YES\n");
}else{
printf("NO\n");
}
}
}
}