找球号(一)
时间限制:3000 ms | 内存限制:65535 KB
难度:3
- 描述
- 在某一国度里流行着一种游戏。游戏规则为:在一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,现在说一个随机整数k(0<=k<=100000100),判断编号为k的球是否在这堆球中(存在为"YES",否则为"NO"),先答出者为胜。现在有一个人想玩玩这个游戏,但他又很懒。他希望你能帮助他取得胜利。
- 输入
- 第一行有两个整数m,n(0<=n<=100000,0<=m<=1000000);m表示这堆球里有m个球,n表示这个游戏进行n次。
接下来输入m+n个整数,前m个分别表示这m个球的编号i,后n个分别表示每次游戏中的随机整数k - 输出
- 输出"YES"或"NO"
- 样例输入
-
6 4 23 34 46 768 343 343 2 4 23 343
- 样例输出
-
NO NO YES YES
-
//代码一AC:用邻接表-hash----就是有点耗内存 #include<stdio.h> #include<malloc.h> struct Node { int num; struct Node *next; }; int main() { int n,m,temp,i; struct Node *t1,*node; scanf("%d%d",&m,&n); node=(struct Node *)malloc(m*sizeof(struct Node)); for(i=0;i<m;++i) { // node[i].num=i; node[i].next=NULL; } for(i=0;i<m;++i) { scanf("%d",&temp); t1=(struct Node *)malloc(sizeof(struct Node)); t1->num=temp; t1->next=node[temp%m].next; node[temp%m].next=t1; } for(i=0;i<n;++i) { scanf("%d",&temp); t1=node[temp%m].next; while(t1) { if(t1->num==temp) { printf("YES\n"); break; } t1=t1->next; } if(t1==NULL) printf("NO\n"); } return 0; } //代码二:二分查找----超时 #include<stdio.h> #include<stdlib.h> /* //递归二分超时 int search(int *p,int t,int low,int high) { int mid; //mid=(high+low)/2; mid=low+(high-low)/2 if(p[mid]==t) return 1; if(low>=high) return 0; else if(p[mid]>t) return search(p,t,low,mid-1); else return search(p,t,mid+1,high); } */ int search(int *p,int t,int low,int high)//仍然超时 { int mid; while(low<=high) { mid=low+(high-low)/2; if(p[mid]==t) return 1; else if(p[mid]<t) low=mid+1; else high=mid-1; } return 0; } int main() { int n,m,i,j,t,flag=1; int *p; scanf("%d%d",&m,&n); p=(int *)malloc((m+1)*sizeof(int)); for(i=1;i<=m;++i) scanf("%d",&p[i]); for(i=m;flag&&i>0;--i) { flag=0; for(j=1;j<m;++j)//事实证明我的排序超时了 if(p[j]>p[j+1]) { flag=1; p[j]=p[j]^p[j+1]; p[j+1]=p[j]^p[j+1]; p[j]=p[j]^p[j+1]; } } for(i=1;i<=n;++i) { scanf("%d",&t); if(search(p,t,1,m)) printf("YES\n"); else printf("NO\n"); } return 0; } //代码三:网上AC代码,也是二分 #include<stdio.h> #include<algorithm> using namespace std; int a[1000005]; int main() { int n,s,t,i,j,flag1; scanf("%d %d",&s,&n); for(i=0;i<s;i++) { scanf("%d",&a[i]); } sort(a,a+s); /* for(i=s;flag1&&i>0;--i)//改成冒泡超时 { flag1=0; for(j=1;j<s;++j) if(a[j]>a[j+1]) { flag1=1; a[j]=a[j]^a[j+1]; a[j+1]=a[j]^a[j+1]; a[j]=a[j]^a[j+1]; } } */ for(i=0;i<n;i++) { int first=0,last=s,mid,flag=0;//**标记**// scanf("%d",&t); while(first<=last)//**二分**// { mid=first+(last-first)/2; if(a[mid]==t) { flag=1; break; } else if(a[mid]<t) first=mid+1; else last=mid-1; } if(flag==1) printf("YES\n"); else printf("NO\n"); } return 0; } //代码四:最优代码
2012年12月7日-----现在回过头来看 顿时明白了 #include <stdio.h> #define MAXN 3125010 int vis[MAXN] = {0} ; // vis数组中存储的就是一个32位的二进制数,下标i代表所得数是32的多少倍,
//而其中存储的二进制数的每一位则代表所得数的关于32的模,很巧妙.. int main() { int m , n , x ; int i ; scanf("%d%d", &m , &n ) ; for( i = 0 ; i < m ; ++i ) { scanf("%d", &x ) ; vis[ x / 32 ] |= 1 << x % 32 ; } for( i = 0 ; i < n ; ++i ) { scanf("%d", &x ) ; if( vis[ x / 32 ] & ( 1 << x % 32 ) ) printf("YES\n"); else printf("NO\n"); } return 0 ; }