interviewstreet-median -类别search

题目来源:https://www.interviewstreet.com/challenges/dashboard/#problem/4fcf919f11817

解题报告:

这道题我用的算法是最普通的算法,数组是排序的。删除操作时,用二分查找找到那个元素,然后数组后面的元素往前移一格。增加操作时,用二分查找找到元素应该在的位置,插入元素,后面的元素依次往后挪。

但是,这道题的关键在于,不能用int,因为两个int相加可能会越界!因为这个WA了好多遍。所以改用long long。

对double,使用math.h中的函数ceil(double)可以取整,根据ceil(v) == v的结果可以判断v是否是整数。

然后输出格式方面 printf("%.0lf", v),代表输出double,且保留0位小数。

/* Sample program illustrating input and output */

#include
#include
using namespace std;

long long a[100001];

void getMedian(int size)
{
    double sum = 0;
    if (size % 2 == 0)
    {
         sum = (double(a[size/2]) + double(a[size/2-1])) / 2;
    }
    else
	sum = a[size/2];
	if (ceil(sum) == sum)
		printf("%.0lf\n", sum);
	else
		printf("%.1lf\n", sum);
}

int findAndRemove(long long key, int size)
{
    int begin = 0;
    int end = size - 1;
    while(begin <= end)
    {
        int mid = (begin+end)/2;
        if (a[mid] < key)
            begin = mid + 1;
        else if (a[mid] > key)
            end = mid - 1;
        else
        {
            int i = mid;
            while(i < size - 1)
            {
                a[i] = a[i+1];
                i++;
            }
            return true;
        }
    }
    return false;
}

int main(){
    int currentSize = 0;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        char operation;
        long long value;
        cin >> operation >> value;
        if (operation == 'r')
        {
            if (currentSize <= 0)
                cout << "Wrong!" << endl;
            else
            {
                if (findAndRemove(value, currentSize))
                {
                    currentSize--;
                    if (currentSize == 0)
                        cout << "Wrong!" << endl;
                    else
                        getMedian(currentSize);
                }
                else
                    cout << "Wrong!" << endl;
            }
        }
        else
        {
            if (currentSize == 0)
                a[0] = value;
            else
            {
                int begin = 0;
                int end = currentSize - 1;
                while(begin <= end)
                {
                    int mid = (begin+end) / 2;
                    if (a[mid] < value)
                        begin = mid + 1;
                    else
                        end = mid - 1;
                }
                int i = currentSize;
                while(i> begin)
                {
                   a[i] = a[i-1];
                    i--;
                }
                a[begin] = value;
             }
             currentSize++;
             getMedian(currentSize);
        }
    }
}


附录:

The median of  M numbers is defined as the middle number after sorting them in order, if  M is odd or the average number of the middle 2 numbers (again after sorting) if  M is even. You have an empty number list at first. Then you can add or remove some number from the list. For each add or remove operation, output the median of numbers in the list.
 
Example : For a set of m = 5 numbers, { 9, 2, 8, 4, 1 } the median is the third number in sorted set { 1, 2, 4, 8, 9 } which is 4. Similarly for set of m = 4, { 5, 2, 10, 4 }, the median is the average of second and the third element in the sorted set { 2, 4, 5, 10 } which is (4+5)/2 = 4.5  
 
Input:
 
The first line is an integer n indicates the number of operations. Each of the next n lines is either "a x" or "r x" which indicates the operation is add or remove.
 
Output:
 
For each operation: If the operation is add output the median after adding x in a single line. If the operation is remove and the number x is not in the list, output "Wrong!" in a single line. If the operation is remove and the number x is in the list, output the median after deleting x in a single line. (if the result is an integer DO NOT output decimal point. And if the result is a double number , DO NOT output trailing 0s.)
 
Constraints:
 
0 < n <= 100,000
 
for each "a x" or "r x" , x will fit in 32-bit integer.
 
Sample Input:
 
7
r 1
a 1
a 2
a 1
r 1
r 2
r 1
 
Sample Output:
Wrong!
1
1.5
1
1.5
1
Wrong!
 
Note: As evident from the last line of the input, if after remove operation the list becomes empty you have to print "Wrong!" ( quotes are for clarity )


你可能感兴趣的:(interviewstreet-median -类别search)