一道算法題:圓桌會議


Total Submission(s) : 179   Accepted Submission(s) : 122
Problem Description
HDU ACM集訓隊的隊員在暑假集訓時經常要討論自己在做題中遇到的問題.每當面臨自己解決不了的問題時,他們就會圍坐在一張圓形的桌子旁進行交流,
經過大家的討論後一般沒有解決不了的問題,這也只有HDU ACM集訓隊特有的圓桌會議,有一天你也可以進來體會一下哦:),在一天在討論的時
候,Eddy想出了一個極爲古怪的想法,如果他們在每一分鐘內,一對相鄰的兩個ACM隊員交換一下位子,那麼要多少時間才能得到與原始狀態相反的座位順
序呢?(即對於每個隊員,原先在他左面的隊員後來在他右面,原先在他右面的隊員在他左面),這當然難不倒其他的聰明的其他隊友們,馬上就把這個古怪的問
題給解決了,你知道是怎麼解決的嗎?
Input
對於給定數目N(1<=N<=32767),表示有N個人,求要多少時間才能得到與原始狀態相反的座位順序(reverse)即對於每個人,原先在他左
面的人後來在他右面,原先在他右面的人在他左面。
Output
對每個數據輸出一行,表示需要的時間(以分鐘爲單位)
Sample Input
4
5
6
Sample Output
2
4
6                         //???
=======================題目到此結束=========================
覺得sample output有問題,應是2 4 7。
我是這麼想的:
把每個人(共N個)編上號後可以把圓桌抽象爲兩列,如:
6人:1  6       5人:   1   5        //一層
        2   5                  2   4        //二層
        3   4                    3          //三層
所謂的‘排成逆序’就是把同一‘層’對應的兩個人互相交換位置。
由圖知,每一‘層’的兩個人之間夾的實際人數爲這一層的‘上面’或‘下面’的人數,而交換每一‘層’兩個人的位置所需的最小時間爲2n+1(n爲這兩個
人之間的人數的最小值)。
易知,總的層數爲|_N/2_|。
爲求出最小時間,對每一‘層’進行遍歷,求其時間之和:
對於任意一層,設層數爲x (1<=x<=|_N/2_|),則這一‘層’上面的人數爲2*(x-1),下面的人數爲N-2x。
因此,交換這一層的兩個人的位置所需的最小時間爲2*min{2(x-1), N-2x }+1。
代碼如下:
/*
*一次只求一種情況
*/
#include<iostream>
using namespace std;
int main()
{
        int N;
        std::cin>>N;
        int m = N/2;
        int sum = 0;
        for(int x = 1 ; x<=m ; ++x)
        {
                int tmp = 2*(x-1) > (N-2*x) ? (N-2*x):2*(x-1);
                sum += 2*tmp+1;
        }
        std::cout<<sum<<endl;
        return 0;

}

哎,貌似簡單的題卻讓我做的這麼複雜,看來水平還有待提高啊!!!
各位大牛給個解釋吧。謝謝了!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章