首页 > 代码库 > UVa 10474 Where is the Marble?

UVa 10474 Where is the Marble?

典型的排序检索问题,需要注意的是返回排好序后要找的第一次出现的位置(序号是从1开始数的)。

开始不知道bsearch()函数,所以自己写了个二分查找,用来用bsearch也同样A过去了。

貌似自己写的比库函数还快0.001秒,嘎嘎!

 

 

  Where is the Marble? 

 

Raju and Meenalove to play with Marbles. They have got a lot of marbles with numbers writtenon them. At the beginning, Raju would place the marbles(弹子) one afteranother in ascending order(按升序排列)of the numberswritten on them. Then Meena would ask Raju to find the first marble with acertain number. She would count 1...2...3. Raju gets one point for correctanswer, and Meena gets the point if Raju fails. After some fixed number oftrials the game ends and the player with maximum points wins. Today it‘s yourchance to play as Raju. Being the smart kid, you‘d be taking the favor of acomputer. But don‘t underestimate(低估) Meena, she hadwritten a program to keep track how much time you‘re taking to give all theanswers. So now you have to write a program, which will help you in your roleas Raju.

Input 

There can bemultiple test cases. Total no of test cases is less than 65. Each test case consistsbegins with 2 integers: N the numberof marbles and Q the numberof queries(询问) Mina would make. The next N lines would contain the numbers written on the N marbles. These marble numbers will not come in any particular order.FollowingQ lines willhave Q queries. Beassured, none of the input numbers are greater than 10000 and none of them arenegative.

Input isterminated by a test case where N = 0 and Q = 0.

Output 

For each test caseoutput the serial number of the case.

For each of thequeries, print one line of output. The format of this line will depend uponwhether or not the query number is written upon any of the marbles. The twodifferent formats are described below:

  • `x found at y‘, if the first marble with number x was found at position y. Positions are numbered 1, 2,..., N.
  • `x not found‘, if the marble with number x is not present.

Look at the outputfor sample input for details.

SampleInput 

4 1

2

3

5

1

5

5 2

1

3

3

3

1

2

3

0 0

SampleOutput 

CASE# 1:

5 found at 4

CASE# 2:

2 not found

3 found at 3

 


Problem-setter:Monirul Hasan Tomal, Southeast University

 

AC代码:

 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7  8 const int maxn = 10000 + 5; 9 int a[maxn], b[maxn];10 bool Find(int a[], int n, int num, int &pos);11 int cmp ( const void *a , const void *b );12 13 int main(void)14 {15     #ifdef LOCAL16         freopen("10474in.txt", "r", stdin);17     #endif18 19     int n, q, i, kase = 0;20     while(scanf("%d %d", &n, &q) == 2 && (n + q))21     {22         printf("CASE# %d:\n", ++kase);23         for(i = 0; i < n; ++i)24             scanf("%d", &a[i]);25         for(i = 0; i < q; ++i)26             scanf("%d", &b[i]);27         qsort(a, n, sizeof(int),cmp);28         int pos;29         for(i = 0; i < q; ++i)30         {31             if(Find(a, n, b[i], pos))32             {33                 int j = pos;34                 while(a[j] == a[pos] && j >= 0)//要找第一个数35                     --j;36                 printf("%d found at %d\n", b[i], j + 2);37             }38             else39                 printf("%d not found\n", b[i]);40         }41     }42     return 0;43 }44 //二分查找45 bool Find(int a[], int n, int num, int &pos)46 {47     int left = 0, right = n - 1;48     int mid = (left + right) / 2;49     while(left <= right)50     {51         if(a[mid] == num)52         {53             pos = mid;54             return true;55         }56         if(a[mid] < num)57         {58             left = mid + 1;59             mid = (left + right) / 2;60             continue;61         }62         if(a[mid] > num)63         {64             right = mid - 1;65             mid = (left + right) / 2;66         }67     }68     return false;69 }70 int cmp ( const void *a , const void *b )71 {72     return *(int *)a - *(int *)b;73 }
代码君

下面是百度百科中bsaerch的用法:

 

用 法: void *bsearch(const void *key, const void *base, size_t nelem, size_t width, int(*fcmp)(const void *, const *));
语法:
#include <stdlib.h> void *bsearch( const void *key, const void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );
参数:第一个:要查找的关键字。第二个:要查找的数组。第三个:指定数组中元素的数目。第四个:每个元素的长度(以字符为单位)。第五个:指向比较函数的指针。
功能: 函数用折半查找法在从数组元素buf[0]到buf[num-1] 匹配参数key。如果函数compare 的第一个参数小于第二个参数,返回负值;如果等于返回零值;如果大于返回正值。数组buf 中的元素应以升序排列。函数bsearch()的返回值是指向匹配项,如果没有发现匹配项,返回NULL

 

 

 

用bsearch的AC代码:

 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7  8 const int maxn = 10000 + 5; 9 int a[maxn], b[maxn];10 int cmp ( const void *a , const void *b );11 12 int main(void)13 {14     #ifdef LOCAL15         freopen("10474in.txt", "r", stdin);16     #endif17 18     int n, q, i, kase = 0;19     while(scanf("%d %d", &n, &q) == 2 && (n + q))20     {21         printf("CASE# %d:\n", ++kase);22         for(i = 0; i < n; ++i)23             scanf("%d", &a[i]);24         for(i = 0; i < q; ++i)25             scanf("%d", &b[i]);26         qsort(a, n, sizeof(int),cmp);27         int pos, *p;28         for(i = 0; i < q; ++i)29         {30             p = (int *)bsearch(&b[i], a, n, sizeof(int), cmp);31             if(p != NULL)32             {33                 pos = p - a;34                 int j = pos;35                 while(a[j] == a[pos] && j >= 0)//要找第一个数36                     --j;37                 printf("%d found at %d\n", b[i], j + 2);38             }39             else40                 printf("%d not found\n", b[i]);41         }42     }43     return 0;44 }45 int cmp ( const void *a , const void *b )46 {47     return *(int *)a - *(int *)b;48 }
代码君