UvaOJ 10763
题目意思很明确:就是输入一组数,看是否能成对,1 2 和 2 1这样的。(If a student wants to go from A to B, there must be another student who wants to go from B to A. )
我看到有人是这样写的代码,我非常不解!什么情况,这也能通过么?(的确是通过了),但是如果我输入这样一组数:
4
1 2
2 4
2 1
4 2
0
那么正确答案应该是YES ,若是这样代入下面这个代码,,那么答案是NO! ( 1 2 和 2 4 交叉到了)
类似然而这样的代码非常多,希望大家不要因为某些代码通过 而不去质疑是否真的正确。。
#include<iostream> //erroy 但是这个代码可以通过,,,,
#include<cstdio>
const int MAXN = 500005;
int arr[MAXN];
void init_arr() {
for (int i = 0; i < MAXN; i ++) {
arr[i] = i;
}
}
void swap_arr (int a, int b) {
int t = arr[a];
arr[a] = arr[b];
arr[b] = t;
}
bool isOk() {
for (int i = 0; i < MAXN; i ++) {
if (arr[i] != i) {
return false;
}
}
return true;
}
int main() {
int n;
int a, b;
while (scanf("%d", &n) != EOF) {
getchar();
if (n == 0) break;
init_arr();
for (int i = 0; i < n; i ++) {
scanf("%d%d", &a, &b);
swap_arr(a, b);
}
if (isOk()) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}
----------------------------------------------------------------------------------------------------------------------
但是这个思路是很好的!不过需要稍作改进!
影响答案的结果是这个顺序的问题,如果排序后为
1 2
2 1
2 4
4 2
再带进检测,那么答案就OK了!
--------------------------------------------------------------------------------------------------
问题来了,怎么排,我有一个解决排序的方法:
在这里设置了一个结构体,如果输入两个数之和相等就排在一起解决 ,将1 2 与2 4 分开关系!
由于不可能出现和相等,数字还能进行交叉的情况,所以这个方法可行
这个题缺少不了排序的问题
还要考虑排序用哪个,对于50000这样的数 O(n平方)已经支撑不了了(那么冒泡,选择排序就不要想了)
可以选用有分治思想的 快排,归并排,(堆排序就算了吧,写着麻烦)这些都是O(nlog n)
这题是有难度的,好好练习排序。
--------------------------------------------------------------------------------------------------
AC了 ,哦耶!
#include<stdio.h>
typedef struct
{
int beg;
int end;
int sum;
}stu;
stu st[500000];
stu st1[500000];
int sort(int l , int h) //用的是归并排序 Nlog2 N 可以应对10的六次方个数,所以大胆的用!
{
if(h-l<=1)return 0;
int i,mid = (l+h)/2;
sort(l,mid);
sort(mid,h);
int j = mid;
int k =0;
i = l;
while(i<mid && j<h)
{
if(st[i].sum <st[j].sum)
{st1[k++] = st[i++];}
else if(st[i].sum > st[j].sum )
{st1[k++] = st[j++];}
else
{
if(st[i].beg <=st[j].beg )
{
st1[k++] = st[i++];
}
else
{
st1[k++] = st[j++];
}
}
}
for(;j<h;j++)
st1[k++]=st[j];
for(;i<mid;i++)
st1[k++]=st[i];
k=0;
for(i=l;i<h;i++)
st[i] = st1[k++];
}
int c[500000];
int main()
{
int n,i;
while(1)
{
scanf("%d",&n);
if(n==0)break;
for(i=0;i<n;i++)
{
scanf("%d %d",&st[i].beg,&st[i].end);
st[i].sum = st[i].beg + st[i].end ;
}
if(n%2==0)
{
sort(0,n);
int t;
for(i=0;i<n;i++)
c[i]=i;
for(i=0;i<n;i++)
{
t = c[st[i].beg];
c[st[i].beg] = c [st[i].end];
c [st[i].end] = t;
}
for(i=0;i<n;i++)
if(c[i] != i)break;
if(i==n)printf("YES\n");
else printf("NO\n");
}
else printf("NO\n");
}
return 0;
}