UVa 669 - Defragment(DFS)

题意

这题看了好久才懂什么意思。

简单地说就是给出一个数字原来的位置,和最后的位置,求移动顺序。

输入簇(cluster)的总数和文件个数,每个文件个数后面跟着的是各个簇的原始位置。最后要按顺序排下来。

思路

分两种情况。

  1. 如果没有环,直接DFS然后换掉。

  2. 如果有环,从后面开始找到第一个空的位置,然后把数移过去,然后就递归了。

代码

 
 
  1. #include <cstdio>
  2. #include <stack>
  3. #include <set>
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. #include <queue>
  8. #include <functional>
  9. #include <cstring>
  10. #include <algorithm>
  11. #include <cctype>
  12. #include <ctime>
  13. #include <cstdlib>
  14. #include <fstream>
  15. #include <string>
  16. #include <sstream>
  17. #include <map>
  18. #include <cmath>
  19. #define LL long long
  20. #define lowbit(x) ((x) & (-x))
  21. #define MP(a, b) make_pair(a, b)
  22. #define MS(arr, num) memset(arr, num, sizeof(arr))
  23. #define PB push_back
  24. #define F first
  25. #define S second
  26. #define ROP freopen("input.txt", "r", stdin);
  27. #define BitCount(x) __builtin_popcount(x)
  28. const double PI = acos(-1.0);
  29. const int INF = 0x3f3f3f3f;
  30. using namespace std;
  31. const int MAXN = 1e4 + 100;
  32. const int MOD = 20071027;
  33. typedef pair<int, int> pii;
  34. typedef vector<int>::iterator viti;
  35. typedef vector<pii>::iterator vitii;
  36. int num[MAXN], vis[MAXN], N;
  37. void DFS(int n)
  38. {
  39. if (num[num[n]] == 0)
  40. {
  41. printf("%d %d\n", n, num[n]);
  42. num[num[n]] = -1;
  43. num[n] = 0;
  44. return;
  45. }
  46. if (vis[num[num[n]]])
  47. {
  48. for (int i = N; i > 0; i--)
  49. {
  50. if (num[i] == 0)
  51. {
  52. printf("%d %d\n", n, i);
  53. num[i] = num[n];
  54. num[n] = 0;
  55. return;
  56. }
  57. }
  58. }
  59. vis[n] = 1;
  60. DFS(num[n]);
  61. printf("%d %d\n", n, num[n]);
  62. num[num[n]] = -1;
  63. num[n] = 0;
  64. }
  65. int main()
  66. {
  67. //ROP;
  68. int T, i, j, nfile, n;
  69. scanf("%d", &T);
  70. while (T--)
  71. {
  72. MS(num, 0);
  73. int pos = 1, tmp;
  74. scanf("%d%d", &N, &nfile);
  75. for (i = 0; i < nfile; i++)
  76. {
  77. scanf("%d", &n);
  78. for (j = 0; j < n; j++)
  79. {
  80. scanf("%d", &tmp);
  81. num[tmp] = pos++;
  82. if (tmp == pos - 1) num[tmp] = -1; //already placed in the correct position
  83. }
  84. }
  85. bool rec = false;
  86. for (i = 1; i <= N; i++)
  87. {
  88. if (num[i] && num[i] != -1)
  89. {
  90. MS(vis, 0);
  91. vis[i] = 1;
  92. DFS(i);
  93. rec = true;
  94. }
  95. }
  96. if (!rec) puts("No optimization needed");
  97. if (T) puts("");
  98. }
  99. return 0;
  100. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值