描述
您正在参与“新一代”操作系统和NG文件系统的开发。在该文件系统中,所有磁盘空间被分成相等大小的N个簇,由1到N的整数编号。每个文件占据盘的任意区域中的一个或多个簇。未被文件占用的所有群集都被视为免费。如果文件的所有集群都以自然顺序位于连续的磁盘集群中,则可以以最快的方式从磁盘读取文件。
以恒定速度旋转磁盘意味着访问其集群需要不同的时间量。因此,读取位于磁盘开头附近的簇比读取位于其末端附近的簇执行得更快。因此,所有文件都按照从1到K的整数按照访问频率下降的顺序编号。在文件在磁盘上的最佳放置下,文件号1将占据集群1,2,...,S1,文件号2将占用集群S1 + 1,S1 + 2,...,S1 + S2和等等(这里Si是第i个文件占用的簇数)。
为了以最佳方式将文件放在磁盘上,执行集群移动操作。一个群集移动操作包括从磁盘读取一个占用的群集到内存并将其内容写入一些空闲群集。在那之后,第一个被宣布自由,第二个被宣布为被占领。
您的目标是通过执行尽可能少的群集移动操作,以最佳方式将文件放在磁盘上。
输入
输入文件的第一行包含两个由空格分隔的整数N和K(1 <= K <N <= 10000)。然后,K行跟随,每个都描述一个文件。第i个文件的描述以整数Si开始,该整数Si表示第i个文件中的簇数(1 <= Si <N)。然后,Si整数按空格分隔,以自然顺序指示磁盘上此文件的簇编号。
输入文件中的所有群集编号都不同,磁盘上始终至少有一个空闲群集。
输出
您的程序应该向输出文件写入以最佳方式将文件放在磁盘上所需的任何群集移动操作序列。由单个空格分隔的两个整数Pj和Qj应代表每个簇移动操作。 Pj给出了数据应该移动的簇号,而Qj给出了该数据应该移动到的簇号。
执行的集群移动操作的数量应尽可能小。如果磁盘上的文件已经以最佳方式放置,则输出应仅包含字符串“无需优化”。
样例输入
20 3 4 2 3 11 12 1 7 3 18 5 10
样例输出
2 1 3 2 11 3 12 4 18 6 10 8 5 20 7 5 20 7
#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; } }
来源:https://www.xuebuyuan.com/zh-hant/828723.html
原文地址:https://www.cnblogs.com/sweet-ginger-candy/p/11518218.html