[关闭]
@w616561153 2019-11-21T20:15:08.000000Z 字数 2004 阅读 924

CF1255C O(nlogn)超时


C. League of Leesins

CF-1255C League of Leesins

题目大意:

一个长度为n的数列,可以将其每三个一组,拆成个数列.例如,数列,可以将其拆成这三个数列。下面给出拆过之后的,顺序打乱的个数列,让你找出原数列的情况.

输入

5
4 3 2
2 3 5
4 1 2

输出

1 4 2 3 5

样例说明

有五个数,那么就有三个被拆分的数列,但它们的顺序都被打乱了。
还原为正常的顺序,(情况不唯一,还可以反过来)则原序列为

TLE代码

  1. //65388014 Nov/20/2019 00:32UTC+8 w616561153 1255C - League of Leesins GNU C++11 Time limit exceeded on pretest 5 2000 ms 24000 KB
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. const int MAXN = 1e5 + 50;
  6. inline int read()
  7. {
  8. int res = 0;
  9. char ch;
  10. ch = getchar();
  11. while(!isdigit(ch))
  12. ch = getchar();
  13. while(isdigit(ch)){
  14. res = res * 10 + ch - 48;
  15. ch = getchar();
  16. }
  17. return res;
  18. }
  19. struct Node
  20. {
  21. int a, b, c;
  22. bool operator < (const Node &i) const{
  23. if(a == i.a){
  24. if(b == i.b)
  25. return c < i.c;
  26. return b < i.b;
  27. }
  28. return a < i.a;
  29. }
  30. };
  31. set<Node> st;
  32. stack<int> s;
  33. queue<int> q;
  34. int vis[MAXN];
  35. int main()
  36. {
  37. int n;
  38. scanf("%d", &n);
  39. for(int i = 1; i <= n - 2; i ++){
  40. int t1, t2, t3;
  41. t1 = read(), t2 = read(), t3 = read();
  42. st.insert(Node{t1, t2, t3}); //把三个数的全排列加入集合。因为无法保证按某一种顺序给出两个数,所以要把三个数可能出现的六种情况都加入集合中.
  43. st.insert(Node{t1, t3, t2});
  44. st.insert(Node{t2, t1, t3});
  45. st.insert(Node{t2, t3, t1});
  46. st.insert(Node{t3, t1, t2});
  47. st.insert(Node{t3, t2, t1});
  48. vis[t1] ++, vis[t2] ++, vis[t3] ++; //记录每个数出现的次数,方便我们找到数列首尾元素.
  49. }
  50. int q1, q2, q3;
  51. for(int i = 1; i <= n; i ++){
  52. if(vis[i] == 1){
  53. q1 = i;
  54. break;
  55. }
  56. }
  57. Node node = *lower_bound(st.begin(), st.end(), Node{q1, 0, 0});
  58. if(vis[node.b] == 2){
  59. q2 = node.b, q3 = node.c;
  60. }
  61. else
  62. q2 = node.c, q3 = node.c;
  63. /*st.erase(Node{q1, q2, q3});
  64. st.erase(Node{q1, q3, q2});
  65. st.erase(Node{q2, q1, q3});
  66. st.erase(Node{q2, q3, q1});
  67. st.erase(Node{q3, q1, q2});
  68. st.erase(Node)*/
  69. q.push(q1), q.push(q2);
  70. for(int tt = 1; tt <= n - 2; tt ++){
  71. s.push(q.front());
  72. int f1, f2, f3;
  73. f1 = q.front(), q.pop();
  74. f2 = q.front();
  75. f3 = (*(lower_bound(st.begin(), st.end(), Node{f1, f2, 0}))).c; //每次都是拿队列中的两个元素去找第三个元素。找到了这个数就是下一个元素.
  76. //因为每次找的时候第三个数都默认为0,所以不会出现涛哥说的那种找不到最后返回st.end()的情况.
  77. st.erase(Node{f1, f2, f3});
  78. st.erase(Node{f1, f3, f2});
  79. st.erase(Node{f2, f1, f3});
  80. st.erase(Node{f2, f3, f1});
  81. st.erase(Node{f3, f1, f2});
  82. st.erase(Node{f3, f2, f1});
  83. q.push(f3);
  84. }
  85. s.push(q.front());
  86. q.pop();
  87. s.push(q.front());
  88. q.pop();
  89. while(!s.empty()){
  90. printf("%d ", s.top());
  91. s.pop();
  92. }
  93. return 0;
  94. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注