您的位置:首页 > 其它

UVa 10474 - Where is the Marble?解题报告

2014-02-02 22:28 411 查看
读入一行2个数字 N 和 Q, N 表示接下来的 N 行数字为 marbles, Q 表示 N 行数字之后的 Q 行数字为 query. 要求把 N 行 marbles 从小到大排序, 然后输出每个 Q 在 marbles 中的位置.注意是第一次出现的位置。

思路:用快速排序对其进行排序,然后用二分查找查找其第一次出现的位置。

可以用其他的排序和搜索算法。如qsort。

#include <iostream>
#include <cstring>
using namespace std;
void quicksort(int a[], int p, int r);//快速排序
int partition(int a[], int p, int r);//将数组从key分为两边,一边大于key,一边小于key
int bin_search(int a[], int n, int key);//二分查找
int marble[10005], finds[10005];

int main()
{
//freopen("data.txt", "r", stdin);
int n, q;
int cases = 1;
while (scanf("%d%d", &n, &q) && n)
{
for(int i = 0; i < n; i++)
scanf("%d", &marble[i]);
for(int i = 0; i < q; i++)
scanf("%d", &finds[i]);
quicksort(marble, 0, n - 1);

printf("CASE# %d:\n", cases++);
for(int i = 0; i < q; i++)
{
int y = bin_search(marble, n, finds[i]);
if(y == -1)
printf("%d not found\n", finds[i]);
else
printf("%d found at %d\n", finds[i], y + 1);
}
}
return 0;
}

int partition(int a[], int p, int r)
{
int middle = p;//middle记录key位置
int x = a[r];//让数组的最后一个数作为中间值key,
for(int j = p; j < r; j++)//利用冒泡的原理将数据分布到key的两边
if(a[j] < x)
{
int temp = a[middle];
a[middle] = a[j];
a[j] = temp;
middle++;
}
int temp = a[r];
a[r] = a[middle];
a[middle] = temp;//让key值居中
return middle;
}
void quicksort(int a[], int p, int r)
{
if(p < r)//当p=r时,说明排序完成
{
int q = partition(a, p, r);
quicksort(a, p, q - 1);
quicksort(a, q + 1, r);
}
}
int bin_search(int a[], int n, int key)
{
int left = 0,
right = n - 1,
flag = -1,
middle;
while (left <= right)
{
middle = left + (right - left) / 2;//防止(left+right)/2越界
if(a[middle] == key)
{
flag = middle;
right = middle - 1;//查找key第一次出现的位置,很巧妙的技巧
//如果要查找key最后一次出现的位置,left = middle + 1
}
if(a[middle] < key)
left = middle + 1;
if(a[middle] > key)
right = middle - 1;
}
if(flag == -1)
return -1;
else
return flag;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: