这道题是我第一次算出来应该用什么复杂度写的题,或许是这一章刚介绍过,500000的数据必须用nlogn,所以我就
想到了二分,它的复杂度是logn,再对n个数据进行遍历,正好是nlogn,前两次TLE了,然后我就对我的做法没信心
了。。。看到一篇博客上说就应该这种方法,然后我就坚定的改自己的算法去了,哈哈,专注度没有达到五颗星,最多
三颗。。。
思路:
我用的是结构体保存的,先对每一对序列排序,然后对第二个元素在第一个元素中二分搜索,用到了
lower_bound,upper_bound,注释里面有写它的功能,其实这两个可以直接调用的。。。注意一下用
upper_bound的时候最后一个元素就ok啦。。。TLE其实不是我的算法的事,而是因为我把这两个函数写到循环里面
了,真傻。。。这样每次循环都会调用的。。。看网上有人说最后套数据n是小于1000的,加个if(n>1000)
for(;;;)就可以啦,哈哈,真聪明,我学会了。。。以后试着用一下。。
贴代码:
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> using namespace std; struct node { int i,j; }a[500005]; int visit[500005];//用来标记是否已经配对过了 int n; int cmp(const void *a,const void *b)//结构体的二级排序 { if(((node *)a)->i != ((node *)b)->i) return ((node *)a)->i - ((node *)b)->i; return ((node *)a)->j - ((node *)b)->j; } int lower_bound(int v)//二分查找,如果要查找的值存在的话,返回第一个等于该元素的位置,否则返回一个它要插入的第一个位置(序列必须先排序) { int m,x = 1,y = n; while(x < y ) { m = x + (y-x)/2; if(a[m].i >= v) y = m ; else x = m + 1; } return x; } int upper_bound(int v)//二分查找,如果存在该元素,就返回它的下一个位置(最后一个除外,就是说如果最后一个元素等于v,就返回的是n),如果不存在,就返回它插入后仍有序的序列 { int m; int x = 1; int y = n; while(x < y) { m = x +(y -x)/2; if(a[m].i<=v) x = m+1; else y = m; } return x; } int main() { int i,j; while(cin >> n, n) { memset(visit,0,sizeof(visit)); for(i=1; i<=n; i++) { // cin >> a[i].i >> a[i].j;//cin输入流比较费时 scanf("%d%d",&a[i].i,&a[i].j); } qsort(a+1,n,sizeof(a[0]),cmp); // for(i=1; i<=n; i++) // { //cin >> a[i].i >> a[i].j; // scanf("%d%d",&a[i].i,&a[i].j); // cout << a[i].i << " "<< a[i].j << endl; // } int flag1 = 0; for(i=1; i<=n; i++) { if(visit[i] == 1)//配对过的不再访问 continue; int flag = 0; int first = lower_bound(a[i].j); int last = upper_bound(a[i].j); // cout << "first = " << first << " " << last << endl; if(a[first].i != a[i].j)//没有与之配对的直接退出输出NO { flag1 =1; break; } if(last == n)//把n的情况特判一下 last ++; for(j=first; j<last; j++) { if(visit[j] == 1) continue; if(a[j].j == a[i].i) { visit[j] = 1; flag = 1; break; } } if(!flag) { flag1 = 1; break; } visit[i] = 1; } if(flag1) cout << "NO" << endl; // puts("NO"); else cout << "YES" << endl; //puts("YES"); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-03 14:07:13