Notes of assignments in week 2

Q1 找第k小的数

设计一个平均时间为O(n)的算法,在n(1<=n<=1000)个无序的整数中找出第k小的数。

提示:函数int partition(int a[],int left,int right)的功能是根据a[left]~a[right]中的某个元素x(如a[left])对a[left]~a[right]进行划分,划分后的x所在位置的左段全小于等于x,右段全大于等于x,同时利用x所在的位置还可以计算出x是这批数据按升非降序排列的第几个数。因此可以编制int find(int a[],int left,int right,int k)函数,通过调用partition函数获得划分点,判断划分点是否第k小,若不是,递归调用find函数继续在左段或右段查找。

输入格式:
输入有两行:
第一行是n和k,0<k<=n<=10000
第二行是n个整数

输出格式:
输出第k小的数

输入样例:
在这里给出一组输入。例如:

10 4
2 8 9 0 1 3 6 7 8 2

输出样例:
在这里给出相应的输出。例如:

2

Notes

(1) Explicitly write

return 0;

at the end of the func which returns an int. In VS c++ it's allowed not to write such a statement but it's not allowed in PTA.
Thus the code

int find(int a[], int left, int right, int k)
{
    ...
        if (x == k)
        {
            cout << a[x];
            return 0;
        }
  ...
}

is not preferable, while

int find(int a[], int left, int right, int k)
{
    ...
        if (x == k)
        {
            cout << a[x];
            return 0;
        }
  ...

    return 0;
}

is correct.

(2) in the partition() func of the quicksort algor,

int partition(int a[], int left, int right)
{
  ...
    while (left < right)  // it's actually swapping values
    {
        while (a[0] <= a[right])
            right--;
        ...

        while (&& a[0] >= a[left])
            left++;

        ...
    }
  ...
}

is wrong. suppose that the input is

1 2 3 4 5 6 7 8 9 10

and the pivot is the first elem, the statement

right--;

will be executed continuously, even if the value of the right var is less than 0, which makes the program access other parts of the memory rathen than where the array is stored. To avoid such an error

left < right

should be added to the condition, thus the conditions will be like

while (left < right && a[0] <= a[right])

and

while (left < right && a[0] >= a[left])

(3) For the question here, the condition in the find() func should be

left <= right

rather than

left < right

some imgs can show the differences. Notice the highligted row.

The original algor cannot solve the problem here since as long as left >= right, it will not call the find() func, making values in the position where left == right cannot be found.

Q2 求逆序对数目

注意:本问题算法的时间复杂度要求为O(nlogn), 否则得分无效

题目来源:http://poj.org/problem?id=1804 Background Raymond Babbitt drives his brother Charlie mad. Recently Raymond counted 246 toothpicks spilled all over the floor in an instant just by glancing at them. And he can even count Poker cards. Charlie would love to be able to do cool things like that, too. He wants to beat his brother in a similar task.

Problem Here's what Charlie thinks of. Imagine you get a sequence of N numbers. The goal is to move the numbers around so that at the end the sequence is ordered. The only operation allowed is to swap two adjacent numbers. Let us try an example: Start with: 2 8 0 3 swap (2 8) 8 2 0 3 swap (2 0) 8 0 2 3 swap (2 3) 8 0 3 2 swap (8 0) 0 8 3 2 swap (8 3) 0 3 8 2 swap (8 2) 0 3 2 8 swap (3 2) 0 2 3 8 swap (3 8) 0 2 8 3 swap (8 3) 0 2 3 8

So the sequence (2 8 0 3) can be sorted with nine swaps of adjacent numbers. However, it is even possible to sort it with three such swaps: Start with: 2 8 0 3 swap (8 0) 2 0 8 3 swap (2 0) 0 2 8 3 swap (8 3) 0 2 3 8

The question is: What is the minimum number of swaps of adjacent numbers to sort a given sequence?Since Charlie does not have Raymond's mental capabilities, he decides to cheat. Here is where you come into play. He asks you to write a computer program for him that answers the question in O(nlogn). Rest assured he will pay a very good prize for it.

输入格式:
The first line contains the length N (1 <= N <= 1000) of the sequence; The second line contains the N elements of the sequence (each element is an integer in [-1000000, 1000000]). All numbers in this line are separated by single blanks.

输出格式:
Print a single line containing the minimal number of swaps of adjacent numbers that are necessary to sort the given sequence.

输入样例:
在这里给出一组输入。例如:

6
-42 23 6 28 -100 65537

输出样例:
在这里给出相应的输出。例如:

5

Notes

(1) When an extern var called count is declared, the IDE warned that "count is ambiguous". Maybe "count" is a reserved identifier and we can use other names instead.

(2) The extern var should be put before all funcs that will call it.

(3) Remember to free the space of an array after using the new statement.

int *a = new int[len];

...

delete[]a;

(4) Some errors occured in the MSort() func when I tried creating an array to store values before merging.

void MSort(int from[], int to[], int low, int high)
{
    if (low == high)
        ...
    else
    {
        ...
    
        int *twoHalf = new int[1000];
        // int *twoHalf = new int[high - low + 2];
        // int twoHalf[1000];
    
        MSort(from, twoHalf, low, mid);
        MSort(from, twoHalf, mid + 1, high);

    ...
    }

    return;
}

I wanted to allocate as less space as possible to store values thus firstly used

int *twoHalf = new int[high - low + 2];

but an exception was raised: "ptaQ2.exe has triggered a breakpoint.". I don't know the reason yet. both

int *twoHalf = new int[1000];

And

int twoHalf[1000];

works well.


I'm not yet familiar with some frequently used sorting algors. And I forgot some c++ basics. QAQ
I'm gonna review them during this period.

猜你喜欢

转载自www.cnblogs.com/Chunngai/p/11484146.html