圆桌会议

圆桌会议

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 10   Accepted Submission(s) : 10
Problem Description
HDU ACM集训队的队员在暑假集训时经常要讨论自己在做题中遇到的问题.每当面临自己解决不了的问题时,他们就会围坐在一张圆形的桌子旁进行交流,经过大家的讨论后一般没有解决不了的问题,这也只有HDU ACM集训队特有的圆桌会议,有一天你也可以进来体会一下哦:),在一天在讨论的时候,Eddy想出了一个极为古怪的想法,如果他们在每一分钟内,一对相邻的两个ACM队员交换一下位子,那么要多少时间才能得到与原始状态相反的座位顺序呢?(即对于每个队员,原先在他左面的队员后来在他右面,原先在他右面的队员在他左面),这当然难不倒其他的聪明的其他队友们,马上就把这个古怪的问题给解决了,你知道是怎么解决的吗?
 

Input
对于给定数目N(1<=N<=32767),表示有N个人,求要多少时间才能得到与原始状态相反的座位顺序(reverse)即对于每个人,原先在他左面的人后来在他右面,原先在他右面的人在他左面。
 

Output
对每个数据输出一行,表示需要的时间(以分钟为单位)
 

Sample Input
456
 

Sample Output
246
 

Author
Eddy
 

Source
杭电ACM省赛集训队选拔赛之热身赛
题目大意:
输入一个数字N,表示有N个人围成一圈。题目要求,每分钟只能交换相邻的两个人,问至少需要多少次分钟,就可以吧每一个人的左右两边都相互交换。(既为,原来在左边的人,转化后,变成在右边。原来在右边的人,转化后,最后变成在左边。)。
其中,这一题就是冒泡法的思想,两两交换。把所以人围成的圈圈分成左右两边,分别对左边两边进行冒泡处理,比如有N个人,1~N/2,需要交换的次数分别是N/2-1,N/2-2,N/2-3.....1,右边的人则是N-N/2个人,同理,需要交换的次数为N-N/2-1,N-N/2-2,N-N/2-3....1.
其中要注意的事N-N/2不一定等于N/2,因为在编译器中都是默认向下取整的,5-5/2=3<>5/2=2。(错了好多次了的,额,后来才发现的。。。)而且,上述次数的相加,也正好是等差数值的相加,可以直接利用等差求和公式分别求出左右两边的次数,即为分钟数。相加所得即为所求的最短时间;
 1 #include<stdio.h>
 2 #define Add(a) (a+1)*a/2    /*等差求和公式*/
 3 int main()
 4 {
 5     int NUM,sum;
 6     while(scanf("%d",&NUM)!=EOF)
 7     {
 8         sum=(NUM/2)-1;
 9         NUM=NUM-NUM/2-1;
10         printf("%d\n",Add(sum)+Add(NUM));
11     }
12     return 0;
13 }
View Code

修改:2015.6.1 

补充:

  如果有M个数的一维数组,每次交换只能两两交换,要把这个数组都倒置,

  需要交换((1+(M-1))*(M-1))/2=>M*(M-1)/2次(类似于冒泡排序)、

  所以,对于一个圆,要求交换次数最少。我们可以把园分割成两半,

  分别看出两个一维的数组,把这两部分相加交换的次数总和即可。

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 int ADD(int N)/*求和公式*/
 6 {
 7     if(N%2)return((N-1)/2*N);
 8     else return N/2*(N-1);
 9 }
10 int main()
11 {
12     int N;
13     while(scanf("%d",&N)!=EOF)
14     {
15         printf("%d\n",ADD(N-N/2)+ADD(N/2));
16     }
17     return 0;
18 }
View Code

 

posted @ 2014-08-22 13:06  Wurq  阅读(234)  评论(0编辑  收藏  举报