題目來源:http://poj.org/problem?id=1033
解題報告:
這道題主要是問,要至少挪幾步,才能把各個節點的位置移到應該在的位置,並把要移動的步驟輸出。
方法一:
我這裏取了數組:
a[i] 代表在i位置放了應該放在a[i]位置的節點
b[i] 代表應該放在i位置的節點現在在b[i]位置
搜索的時候從i=1開始,如果a[i] == i,代表節點位置正確,不用移動
如果a[i] != i,代表位置擺放不正確
這裏,又分兩種情況:
1) 如果a[i] == 0,說明 i位置現在爲空,只要簡單的將節點從b[i] 移到 i 就可以了。
2) 如果a[i] != 0,說明i位置現在有節點佔着,要先把i位置上的節點放到a[i] 位置,而如果a[a[i]] != 0,則意味着a[i]位置上也有節點佔着,要先將a[i]位置上的節點移到正確的位置。於是,我取了一個棧,把這些搜索過程中遇到的節點放入棧中,直到搜索到爲空的位置,然後再一次把棧中的節點移到他們正確的位置。當然,也有可能最後出現一個循環,所以,我用了c[i]來記錄棧中已有的節點,c[i]=1代表此次搜索,i位置已被訪問過,如果出現了循環,則直接從最後的節點往前搜一個空位置,然後把棧頂的節點先移到空位置,等其餘節點都在正確的位置時,再把那個節點從空位置已到它應在的正確位置。
方法二:
想了一下,其實用DFS的思路就行了,晚上補充代碼和解題報告。
方法一:
#include <iostream>
#include <stack>
using namespace std;
#define N 10000
int main() {
int a[N] = {0};
int b[N] = {0};
int c[N] = {0};
int n;
int k;
cin >> n;
cin >> k;
int m = 1;
for (int i=1; i <=k; i++) {
int s;
cin >> s;
for (int j=1; j <=s; j++) {
int tmp;
cin >> tmp;
a[tmp] = m;
b[m] = tmp;
m++;
}
}
stack<int> Q;
bool needed = false;
for (int i=1; i<m; i++) {
int t = i;
while(a[t]!=t) {
needed = true;
if (c[t] == 1) {
for (int j =n; j>0; j--) {
if (a[j] == 0) {
cout << b[Q.top()] << " " << j << endl;
b[Q.top()] = j;
a[j] = Q.top();
Q.pop();
break;
}
}
break;
}
Q.push(t);
if (a[t]==0) {
break;
}
else {
c[t] = 1;
t = a[t];
}
}
while(!Q.empty()) {
int top = Q.top();
Q.pop();
cout << b[top] << " " << top << endl;
a[top]= top;
a[b[top]] = 0;
b[top] = top;
}
for (int j =0; j < N; j++) {
c[j] = 0;
}
}
if (!needed){
cout << "No optimization needed" << endl;
}
}
附錄:
Description
Rotation of the disk with constant speed implies that various amounts of time are needed for accessing its clusters. Therefore, reading of clusters located near the beginning of the disk performs faster than reading of the ones located near its ending. Thus, all files are numbered beforehand by integers from 1 to K in the order of descending frequency of access. Under the optimal placing of the files on the disk the file number 1 will occupy clusters 1, 2, ..., S1, the file number 2 will occupy clusters S1+1, S1+2, ..., S1+S2 and so on (here Si is the number of clusters which the i-th file occupies).
In order to place the files on the disk in the optimal way cluster-moving operations are executed. One cluster-moving operation includes reading of one occupied cluster from the disk to the memory and writing its contents to some free cluster. After that the first of them is declared free, and the second one is declared occupied.
Your goal is to place the files on the disk in the optimal way by executing the minimal possible number of cluster-moving operations.
Input
All cluster numbers in the input file are different and there is always at least one free cluster on the disk.
Output
The number of cluster-moving operations executed should be as small as possible. If the files on the disk are already placed in the optimal way the output should contain only the string "No optimization needed".
Sample Input
20 3 4 2 3 11 12 1 7 3 18 5 10
Sample Output
2 1 3 2 11 3 12 4 18 6 10 8 5 20 7 5 20 7