您的位置:首页 > 其它

Uvaoj 10763详解+思想(不只是题的思想)

2016-02-03 18:19 148 查看
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;  

    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;  

}  

----------------------------------------------------------------------------------------------------------------------

 [b]但是这个思路是很好的!不过需要稍作改进!  


  影响答案的结果是这个顺序的问题,如果排序后为

  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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: