题目大意:给出 N 组数,若所有 A,B 都有出现对应的 B,A 即 YES,否则 NO。
解题思路:思路蛮简单,一开始直接做没去排序自然是 TLE……根据 N 的奇偶也可以剪枝一下,显然要成对出现才有可能满足条件。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
struct node {
int a, b;
};
node n[500010];
bool cmp (node a, node b) {
if (a.a == b.a) return a.b > b.b;
return a.a > b.a;
}
int main() {
int N;
while (scanf("%d", &N)!= EOF && N) {
memset(n, 0, sizeof(n));
int flag = 1;
for (int i = 0; i < N; i++) {
int a, b;
scanf("%d%d", &a, &b);
if (a < b) {
n[i].a = a;
n[i].b = b;
}
else {
n[i].a = b;
n[i].b = a;
}
}
if (N % 2) {
printf("NO\n");
continue;
}
sort(n, n+N, cmp);
// for (int i = 0; i < N; i++) cout << n[i].a << n[i].b << endl;
for (int i = 0; i < N-1; i+= 2) {
if (n[i].a != n[i+1].a || n[i].b != n[i+1].b) {
flag = 0;
break;
}
}
printf(flag ? "YES\n" : "NO\n");
}
return 0;
}
以下是别人的代码,先初始化,出现一组 A,B 就交换一次,如果出现偶数次会和初始化相同,若不同即 NO。处理的非常巧妙,学习。
#include<iostream>
using namespace std;
#define MAXN 500000+5
int main() {
int n;
while (cin >> n, n) {
int e[MAXN];
for (int i = 1; i <= 500000; i++)
e[i] = i;
for (int i = 0; i < n; i++) {
int a, b;
cin >> a >> b;
swap(e[a], e[b]);
}
int flag = 0;
for (int i = 1; i < 500000; i++)
if (e[i] != i) {
flag = 1;
break;
}
if (flag == 0)
cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
不过做完发现以上两种 AC 代码都有一个很明显的 bug,比如下面这组样例:
2
1 2
1 2
0
都输出 YES,然而根据题意明显是 NO 才对(笑哭)
以下是我认为的正确代码,只不过数据不超过 1000 确实是有些巧,根据题意为 500000 的话直接爆掉了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
int n[1000][1000];
int main() {
int N;
while (scanf("%d", &N)!= EOF && N) {
memset(n, 0, sizeof(n));
int flag = 1;
for (int i = 0; i < N; i++) {
int a, b;
scanf("%d%d", &a, &b);
n[a][b]++;
n[b][a]--;
}
for (int i = 0; i < 1000; i++)
for (int j = 0; j < 1000; j++) {
if (n[i][j]) {
flag = 0;
break;
}
if (!flag) break;
}
printf(flag ? "YES\n" : "NO\n");
}
return 0;
}