现在的位置: 首页 > 综合 > 正文

POJ 1033-Defragment 简单搜索

2013年08月29日 ⁄ 综合 ⁄ 共 3577字 ⁄ 字号 评论关闭

题目来源: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

You are taking part in the development of a "New Generation" operating system and the NG file system. In this file system all disk space is divided into N clusters of the equal sizes, numbered by integers from 1 to N. Each file occupies one or more clusters
in arbitrary areas of the disk. All clusters that are not occupied by files are considered to be free. A file can be read from the disk in the fastest way, if all its clusters are situated in the successive disk clusters in the natural order. 
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

The first line of the input file contains two integers N and K separated by a space(1 <= K < N <= 10000).Then K lines follow, each of them describes one file. The description of the i-th file starts with the integer Si that represents the number of clusters
in the i-th file (1 <= Si < N). Then Si integers follow separated by spaces, which indicate the cluster numbers of this file on the disk in the natural order. 
All cluster numbers in the input file are different and there is always at least one free cluster on the disk. 

Output

Your program should write to the output file any sequence of cluster-moving operations that are needed in order to place the files on the disk in the optimal way. Two integers Pj and Qj separated by a single space should represent each cluster-moving operation.
Pj gives the cluster number that the data should be moved FROM and Qj gives the cluster number that this data should be moved TO. 
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

抱歉!评论已关闭.