南邮 OJ 1871 Sorting Problem II

Sorting Problem II

时间限制(普通/Java) :  1000 MS/ 2000 MS          运行内存限制 : 16384 KByte
总提交 : 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");
			}
		}
	}
}



你可能感兴趣的:(ACM,problem,sorting,II,南邮OJ)