POJ-1455 Crazy tea party
解析:
为使题目保持简单,我们取个特例,5个人。从中任取一人给他赋一个标号1,然后从他沿逆时针方向一次给游戏者编号,这样我们就得到一个序列
(1) 1 2 3 4 5
要使左边的人到右边去,右边的人到左边去,那么下面的序列肯定满足条件
(2) 5 4 3 2 1
由序列(1)变为序列(2),做相邻交换的最少次数正好是(2)的逆序数。由于该序列是环形的,所以下面的序列肯定也符合条件
(3) 4 3 2 1 5
(4) 3 2 1 5 4
(5) 4 3 2 1 5
显然我们要从(2)~(5)中找个逆序数最小的序列,这个序列的逆序数正好是答案。
然后你再多画几个序列,比如 1 2 3 4 5 6,很快就会发现规律。如1 2 3 4 5 6 因该变换到 3 2 1 6 5 4, 1 2 3 4 5 6 7 应该变换到 4 3 2 1 7 6 5。
源码:
为使题目保持简单,我们取个特例,5个人。从中任取一人给他赋一个标号1,然后从他沿逆时针方向一次给游戏者编号,这样我们就得到一个序列
(1) 1 2 3 4 5
要使左边的人到右边去,右边的人到左边去,那么下面的序列肯定满足条件
(2) 5 4 3 2 1
由序列(1)变为序列(2),做相邻交换的最少次数正好是(2)的逆序数。由于该序列是环形的,所以下面的序列肯定也符合条件
(3) 4 3 2 1 5
(4) 3 2 1 5 4
(5) 4 3 2 1 5
显然我们要从(2)~(5)中找个逆序数最小的序列,这个序列的逆序数正好是答案。
然后你再多画几个序列,比如 1 2 3 4 5 6,很快就会发现规律。如1 2 3 4 5 6 因该变换到 3 2 1 6 5 4, 1 2 3 4 5 6 7 应该变换到 4 3 2 1 7 6 5。
源码:
poj1455.c
1 #include <stdio.h>
2
3 int main(void)
4 {
5 int i, t1, t2;
6 int N, n, result;
7
8 scanf("%d", &N); // 测试次数
9 for (i=0; i<N;i++) {
10 scanf("%d",&n); // 单次测试中的人数
11 t1 = n/2;
12 t2 = n - t1;
13 result = (t1*(t1-1))/2 + (t2*(t2-1))/2;
14
15 printf("%d\n",result);
16 }
17 return 0;
18 }
2
3 int main(void)
4 {
5 int i, t1, t2;
6 int N, n, result;
7
8 scanf("%d", &N); // 测试次数
9 for (i=0; i<N;i++) {
10 scanf("%d",&n); // 单次测试中的人数
11 t1 = n/2;
12 t2 = n - t1;
13 result = (t1*(t1-1))/2 + (t2*(t2-1))/2;
14
15 printf("%d\n",result);
16 }
17 return 0;
18 }
posted on 2009-12-26 13:53 John Waken 阅读(567) 评论(0) 编辑 收藏 举报