poj 1804 Brainman

Brainman
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 7873 Accepted: 4299

Description

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.
背景
Raymond Babbitt 快让他的兄弟Charlie疯了。最近Raymond将牙签散落一地然后只需要瞥一眼就能数出来一共扔了246根。他甚至可以数扑克牌(这前后有啥递进关系么,咋翻译啊这....=w=)。Charlie也喜欢做这种看起来超cool的事情,所以他希望能够与他的兄弟一决雌雄。
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:
这里是Charlie想的问题。想想你有N个数字组成的序列。然后要求通过移动数字来排序。只允许进行相邻两个数字的移动。让我们来尝试一个例子。
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
这样序列(2 8 0 3)可以通过九次交换来获得排序序列。然而,他也可以通过3次交换来完成排序。
he 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. Rest assured he will pay a very good prize for it.
他的问题是:排序需要的最小交换次数。既然Charlie没有Raymond的智商,他决定作弊。这里需要你的帮忙。他要求你去写一个程序来获得答案。当然报酬丰厚.....(骗谁呢=w=)

Input

The first line contains the number of scenarios.
For every scenario, you are given a line containing first the length N (1 <= N <= 1000) of the sequence,followed by the N elements of the sequence (each element is an integer in [-1000000, 1000000]). All numbers in this line are separated by single blanks.

第一行包含序列的个数。

对于每一组,将会先提供给你序列的长度N (1 <= N <= 1000),然后提供序列的具体数字,每个数字在[-1000000, 1000000]之间。这一行所有的数字将被空格隔开

Output

Start the output for every scenario with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the minimal number of swaps of adjacent numbers that are necessary to sort the given sequence. Terminate the output for the scenario with a blank line.
输出的开头需要输出一个"Scenario #i:",i表示组数,从1开始。然后单独一行输出需要最少的交换次数。每一组后都有一个空行。
Sample Input
4
4 2 8 0 3
10 0 1 2 3 4 5 6 7 8 9
6 -42 23 6 28 -100 65537
5 0 0 0 0 0

Sample Output

Scenario #1:
3

Scenario #2:
0

Scenario #3:
5

Scenario #4:
0

Source

TUD Programming Contest 2003, Darmstadt, Germany
 
从这次开始俺的翻译嵌在题目中间,一个是对照着看起来方便点,另一点是,我懒得重新排一下版面了Q_Q。主要是能够节省好多地方>_<。
然后这道题就是求逆序数,既然很水....就让我水过吧阿门.....这里用的是归并排序顺便求得逆序数。
 
#include<iostream>
#include<cmath>
#include<algorithm>
#include <stdio.h>
#include <string.h>

#define MAXINT 1111111
#define LENGTH 1111

void Merge_sort(int a[LENGTH], int p, int r);
void Merge(int a[LENGTH], int p, int q, int r);

int inve_sum = 0;

int main(void)
{
	int a[LENGTH];
	int k = 1;
	int number, N;

	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);

	scanf("%d", &number);
	while(number--){
		scanf("%d", &N);
		for (int i = 0;i < N;i ++){
			scanf("%d", &a[i]);
		}
		inve_sum = 0;

		Merge_sort(a, 0, N - 1);
		printf("Scenario #%d:\n", k++);
		printf("%d\n", inve_sum);
		printf("\n");
	}

    	return 1;
}

void Merge_sort(int a[LENGTH], int p, int r){
    int q;
    if (p < r){
        q = (p + r) >> 1;
        Merge_sort(a, p, q);
        Merge_sort(a, q + 1, r);
        Merge(a, p, q, r);
    }
}

void Merge(int a[LENGTH], int p, int q, int r){
    int L[(LENGTH >> 1) + 1], R[(LENGTH >> 1) + 1];
    int n1 = 0, n2 = 0;

    for (int i = p;i <= q;i ++){
        L[n1++] = a[i];
    }
    L[n1] = MAXINT;
    for (int i = q + 1;i <= r;i ++){
        R[n2++] = a[i];
    }
    R[n2] = MAXINT;

    n1 = 0, n2 = 0;
    for (int k = p;k <= r; k++){
        if (L[n1] <= R[n2]){
            a[k] = L[n1];
            n1++;
        }else{
            a[k] = R[n2];
	    inve_sum += q - p + 1 - n1;
            n2++;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值