程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVA - 10570 Meeting with Aliens

UVA - 10570 Meeting with Aliens

編輯:C++入門知識

UVA - 10570 Meeting with Aliens


題目大意:N個外星人圍成一桌坐下,有序的排列指N在N-1與N+1中間,現在給出一個序列,問至少交換幾次可以得到有序的序列。

解題思路:不管結果如何,我們可以假設最終的序列是以某個外星人為起點的有序序列,既然如此,我們可以構造另一個序列,把原來的外星人長度增加一倍,這樣一來,原序列一定是這個構造序列的子序列。然後通過枚舉,可以把最小交換次數求出來。繼而解決下一個問題:如何求最小的交換次數?我們可以把1與1號位置的交換,2與2號位置的交換,這樣求出的序列即是最小的,這個結論可以記住。然後再反過來求一遍即可,因為題目要求是正、反序列。
 

#include 
#include 
using namespace std;

int cal(int A[], int N) {
    int cnt = 0, vis[505] = {0};
    for (int i = 1; i <= N; i++)
        if(!vis[i]) {
            cnt++;
            for (int j = i; !vis[j]; j = A[j])
                vis[j] = 1;
        }
    return N - cnt;
} 

int main() {
    int N, A[1010], B[1010];
    while (scanf("%d", &N), N) {
        for (int i = 1; i <= N; i++) {
            scanf("%d", &A[i]);
            B[N - i + 1] = B[2 * N - i + 1] = A[i + N] = A[i];
        }

        int ans = 1 << 30;
        for (int i = 0; i < N; i++)
            ans = min(ans, cal(A + i, N));

        for (int i = 0; i < N; i++)
            ans = min(ans, cal(B + i, N));

        printf("%d\n", ans);
    }

    return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved