基本介紹
- 中文名:銀河英雄傳說
- 外文名:Ginga Eiyudensetsu
題目
問題描述
輸入檔案
- M i j :i 和 j 是兩個整數(1<=i , j<=30000),表示指令涉及的戰艦編號。
該指令是萊因哈特竊聽到的楊威利發布的艦隊調動指令,並且保證第 i 號戰艦與第 j 號戰艦不在同一列。 - C i j :i 和 j 是兩個整數(1<=i , j<=30000),表示指令涉及的戰艦編號。
該指令是萊因哈特發布的詢問指令。
輸出檔案
樣例輸入
樣例輸出
樣例說明
第一列 | 第二列 | 第三列 | 第四列 | …… | |
初始時 | 1 | 2 | 3 | 4 | …… |
M 2 3 | 1 | 3 2 | 4 | …… | |
C 1 2 | 1 號戰艦與 2 號戰艦不在同一列,因此輸出-1 | ||||
M 2 4 | 1 | 4 3 2 | …… | ||
C 4 2 | 4 號戰艦與 2 號戰艦之間僅布置了一艘戰艦,編號為 3,輸出 1 |
題目分析
C++代碼
#include<iostream>using namespace std;int FindFather(int father[], int pos);void Unite(int father[], int posI, int posJ);int Search(int father[], int posI, int posJ);int main(){ const int MAX = 30000; int *father = new int[MAX+1]; for (int i=0; i<=MAX; i++) //所有的數組元素值均初始化為自身序號的相反數 father[i] = -i; int T; cin >> T; char ch; int posI, posJ; for (int i=0; i<T; i++) { cin >> ch; cin >> posI >> posJ; if (ch == 'M') Unite(father, posI, posJ); else cout << Search(father, posI, posJ) << endl; } delete []father; system("pause"); return 0;}//尋找第i號戰艦所在的整個戰艦佇列的對頭 int FindFather(int father[], int pos){ if (father[pos] < 0) return pos; return FindFather(father, father[pos]);}//合併指令 void Unite(int father[], int posI, int posJ){ //首先各自去尋找所在的整個戰艦佇列的對頭 int fI = FindFather(father, posI); int fJ = FindFather(father, posJ); //第i號戰艦所在的整個戰艦佇列,作為一個整體(頭在前尾在後)接至第j號戰艦所在的戰艦佇列的尾部 int rear = -father[fJ]; //posJ所在佇列的隊尾 father[fJ] = father[fI]; father[fI] = rear; }//查詢指令 int Search(int father[], int posI, int posJ){ int fI = FindFather(father, posI); //posI所在佇列的隊頭 int rear = -father[fI]; //posI所在佇列的隊尾 while (rear != posI && rear != posJ) //尋找posI或posJ在佇列中的位置 rear = father[rear]; if (rear == posJ)//如果先找到posJ,則設posJ = posI,繼續尋找posJ posJ = posI; int len = -1; while (rear != father[fI] && rear != posJ)//尋找posJ在佇列中的位置 { len++; rear = father[rear]; } //如果第i號戰艦與第j號戰艦當前不在同一列上,則輸出-1 if (rear != posJ) len = -1; return len;}
Pascal
PROGRAM P1034 (INPUT, OUTPUT);CONST MAX = 5000;VAR father : ARRAY [1..MAX] OF INTEGER; T, posI, posJ, i : integer; ch : char;{尋找第i號戰艦所在的整個戰艦佇列的對頭}FUNCTION FindFather(pos : integer): integer; begin if father[pos] < 0 then FindFather := pos else FindFather := FindFather(father[pos]); end; {FindFather}{合併指令}PROCEDURE Unite(posI, posJ : integer); var fI, fJ, rear : integer; begin {首先各自去尋找所在的整個戰艦佇列的對頭} fI := FindFather(posI); fJ := FindFather(posJ); {第i號戰艦所在的整個戰艦佇列,作為一個整體(頭在前尾在後)接至第j號戰艦所在的戰艦佇列的尾部} rear := -father[fJ]; {posJ所在佇列的隊尾} father[fJ] := father[fI]; father[fI] := rear; end; {Unite}{查詢指令}FUNCTION Search(posI, posJ : integer): integer; var fI, rear, len : integer; begin fI := FindFather(posI); {posI所在佇列的隊頭} rear := -father[fI]; {posI所在佇列的隊尾} while (rear <> posI) and (rear <> posJ) do {尋找posI或posJ在佇列中的位置} rear := father[rear]; if rear = posJ then {如果先找到posJ,則設posJ = posI,繼續尋找posJ} posJ := posI; len := -1; while (rear <> father[fI]) and (rear <> posJ) do {尋找posJ在佇列中的位置} begin inc(len); rear := father[rear]; end; {while} {如果第i號戰艦與第j號戰艦當前不在同一列上,則輸出-1} if rear <> posJ then len := -1; Search := len; end; {Search}BEGIN {MAIN} for i:=1 to MAX do {所有的數組元素值均初始化為自身序號的相反數} father[i] := -i; readln(T); for i:=1 to T do begin read(ch); read(posI); readln(posJ); if ch = 'M' then Unite(posI, posJ) else writeln(Search(posI, posJ)); end; {for}END.