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
/*172ms,256KB*/
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int source[10001];///该簇所放碎片之前的簇位置
int target[10001];///该簇碎片的目标簇位置
queue<int> q;
int main()
{
int n, k;
while (~scanf("%d%d", &n, &k))
{
memset(source, 0, sizeof(source));
memset(target, 0, sizeof(target));
int s, count = 0, i = 1, j, t = 1; ///count为总碎片数
bool tidy = false;
while (k--)
{
scanf("%d", &s);
count += s;
while (s--)
{
scanf("%d", &j);
source[i] = j;
target[j] = i;
++i;
}
}
for (i = 1; i <= count; ++i)
if (target[i] == 0)///空位置
q.push(i);
if (!q.empty())
tidy = true;
while (!q.empty())
{
i = q.front();
q.pop();
j = source[i];
printf("%d %d\n", j, i);
source[i] = i;
target[i] = i;///更新
target[j] = 0;
if (j <= count)
///多出的空位置放后面,所以我们先把能直接移动的都移动了,再处理后续要移动的
q.push(j);
}
for (i = 1; i <= count; ++i)
if (target[i] != i)
{
if (!tidy)
tidy = true;
printf("%d %d\n", i, count + 1);///先移到末尾
target[count + 1] = target[i];
source[target[i]] = count + 1;
target[i] = 0;
t = i;
///连续整理
while (t <= count)
{
j = source[t];
printf("%d %d\n", j, t);
target[t] = t;
source[t] = t;
target[j] = 0;
t = j;
}
}
if (!tidy)
puts("No optimization needed");
}
}
1698



被折叠的 条评论
为什么被折叠?



