POJ_1455_Crazy tea party_解题思路

题目来源:http://poj.org/problem?id=1455

 题目意译:
有n个人围在桌子前面喝茶,等大家都坐定后,必然有个前后左右顺序,比如:a左边b,b左边c,依次类推,最后一个假设是g,那么他左边必然是a。

形成一个圆环。

现在有个规则,规定每次只能相邻两个人进行交换位置。

请问要经过多少次交换,才能让之前位置交换(b左边a,c左边b,a左边是g)

 

思路:

大家都清楚假定是一排的情况下:

a b c d e f g

如果位置交换后:

g f e d c b a

需要经过n*(n-1)/2次交换(冒泡法进行交换)

 

现在情况是环形,试问能不能将环拆分成两个线性,然后进行交换,再拼接在一起。

举例如下:

a b c d e f g(g后面又是a)

如果分成a b c,d e f g两部分,分别进行逆序,然后连接,是不是满足条件呢?

交换后c b a, g f e d

连接后为:c b a g f e d,在环路中,其实位置更改后为g f e d c b a,是满足条件的。

那么题目得解:

现在问题是假定环形的长度是N,如果进行截图,才能使得交换次数是最少的呢?
假定N的环形,分成一个长度为k,另一个长度是N-k的线段。

那么需要交换的次数为:

k*(k-1)/2

(N-k)*(N-k-1)/2

相加后就是需要交换的总次数。

题目要求交换次数最少。

那么就是求 

k*(k-1)/2+
(N-k)*(N-k-1)/2的最小值。

 

很容易根据公式,二次函数在极值时取N/2的时候。

所以题目对应程序如下:

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3  int main()
 4 {
 5      int n,s;
 6      int pre,sufix;
 7     scanf( " %d ",&n);
 8      while(n--)
 9     {
10         scanf( " %d ",&s);
11         pre=(s>> 1);
12         sufix=s-pre;
13         printf( " %d\n ",(pre*(pre- 1)+sufix*(sufix- 1))/ 2);
14     }
15      // system("pause");
16  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值