洛谷-UVA101 The Blocks Problem

爱被打了一巴掌 2023-05-31 03:11 100阅读 0赞

输入格式

format_png

输出格式

format_png 1

题意翻译

初始时从左到右有n个木块,编号为0~n-1,要求实现下列四种操作:

  • move a onto b: 把a和b上方的木块全部放回初始的位置,然后把a放到b上面
  • move a over b: 把a上方的木块全部放回初始的位置,然后把a放在b所在木块堆的最上方
  • pile a onto b: 把b上方的木块部放回初始的位置,然后把a和a上面所有的木块整体放到b上面
  • pile a over b: 把a和a上面所有的木块整体放在b所在木块堆的最上方

一组数据的结束标志为”quit”,如果有非法指令(a和b在同一堆),应当忽略。

输出:所有操作输入完毕后,从左到右,从下到上输出每个位置的木块编号。 感谢U27114 jxdql2001 提供的翻译

输入输出样例

输入 #1复制

  1. 10
  2. move 9 onto 1
  3. move 8 over 1
  4. move 7 over 1
  5. move 6 over 1
  6. pile 8 over 6
  7. pile 8 over 5
  8. move 2 over 1
  9. move 4 over 9
  10. quit

输出 #1复制

  1. 0: 0
  2. 1: 1 9 2 4
  3. 2:
  4. 3: 3
  5. 4:
  6. 5: 5 8 7 6
  7. 6:
  8. 7:
  9. 8:
  10. 9:

难点:能读懂题目,但找不到一般性规律!
发现4种操作最后的操作都有共通点:a和a上方的木块都放在b堆上。
另外:pile和over其实没有用!!
找到此共通点后,其实就是.
move a:a上方的归位
onto b:b上方的归为
总结而来就是两步操作:归位 和 移动
注:隐藏的条件有 木块在同堆则跳过此操作。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. vector<int> block[30]; //一维固定,二维不固定
  4. int n;//n个块
  5. //初始化
  6. void init()
  7. {
  8. cin>>n;
  9. for(int i=0;i<n;i++)
  10. block[i].push_back(i);
  11. }
  12. //找位置(x:待归为的编号,p:横坐标,h:纵坐标)
  13. void loc(int x,int &p,int &h)
  14. {
  15. for(int i=0;i<n;i++)
  16. for(int j=0;j<block[i].size();j++)
  17. {
  18. if(block[i][j]==x)
  19. {
  20. p=i;
  21. h=j;
  22. }
  23. }
  24. }
  25. //归位操作 (p:横坐标,h:纵坐标)
  26. //p堆>h的所有块归位
  27. void goback(int p,int h)
  28. {
  29. for(int i=h+1;i<block[p].size();i++)
  30. {
  31. int k=block[p][i];
  32. block[k].push_back(k);
  33. }
  34. block[p].resize(h+1);//重置大小(清空操作)
  35. }
  36. //p堆>=h的所有块移动到q之上
  37. void moveall(int p,int h,int q)
  38. {
  39. for(int i=h;i<block[p].size();i++)
  40. {
  41. int k=block[p][i];
  42. block[q].push_back(k);
  43. }
  44. block[p].resize(h);//重置大小
  45. }
  46. void solve()
  47. {
  48. int a,b;
  49. string s1,s2;
  50. while(cin>>s1)
  51. {
  52. if(s1=="quit")
  53. break;
  54. cin>>a>>s2>>b;
  55. int ap=0,ah=0,bp=0,bh=0;
  56. loc(a,ap,ah);
  57. loc(b,bp,bh);
  58. //如果a,b在同一堆,则忽略
  59. if(ap==bp)
  60. continue;
  61. if(s1=="move")//a归位
  62. goback(ap,ah);
  63. if(s2=="onto")//b归位
  64. goback(bp,bh);
  65. moveall(ap,ah,bp);
  66. }
  67. }
  68. void print()
  69. {
  70. for(int i=0;i<n;i++)
  71. {
  72. cout<<i<<":";
  73. for(int j=0;j<block[i].size();j++)
  74. cout<<" "<<block[i][j]<<endl;
  75. }
  76. }
  77. int main()
  78. {
  79. init();
  80. solve();
  81. print();
  82. return 0;
  83. }

发表评论

表情:
评论列表 (有 0 条评论,100人围观)

还没有评论,来说两句吧...

相关阅读

    相关 P1865 A % B Problem

    题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m