• 【牛客刷题】


    CSDN话题挑战赛第2期
    参赛话题:学习笔记

    学习之路,长路漫漫,写学习笔记的过程就是把知识讲给自己听的过程。这个过程中,我们去记录思考的过程,便于日后复习,梳理自己的思路。学习之乐,独乐乐,不如众乐乐,把知识讲给更多的人听,何乐而不为呢?​​​​​​​
     

    目录

    题目描述

    输入描述:

    输出描述:

    示例1

             输入

    输出

    思路 

     AC


    题目描述

    围棋是起源于中国有悠久历史的策略性棋类游戏。它的规则如下:
    1. 棋盘19*19。
    2. 棋子分黑白两色,双方各执一色。
    3. 下法:每次黑或白着一子于棋盘的空点上。棋子下定后,不再向其他点移动。
    4. 棋子的气:一个棋子在棋盘上,与它相邻的空点是这个棋子的“气”(这里相邻是指两个点有公共边)。 相邻的点上如果有同色棋子存在,这些棋子就相互连接成一个不可分割的整体,气合并计算。
    相邻的点上如果有异色棋子存在,此处的气便不存在。
    如果棋子所在的连通块失去所有的气,即为无气之子,不能在棋盘上存在。
    5. 提子:把无气之子清理出棋盘的手段叫“提子”。提子有二种:
    1) 着子后,对方棋子无气,应立即提取对方无气之子。
    2) 着子后,双方棋子都呈无气状态,应立即提取对方无气之子。
    6. 禁着点:棋盘上的任何一空点,如果某方在此下子,会使该子立即呈无气状态,同时又不能提取对方的棋子,这个点叫做“禁着点”,该方不能在此下子。
    7. 禁止全局同形:无论哪一方,在成功进行了着子、提子操作后,棋盘局面不能和任何之前的局面相同。

    你要做的是:输入一些操作,从空棋盘开始模拟这些操作。
    对于每一步,若结果不正确,则输出对应的miss并且忽略这个操作,并在最后输出棋盘的局面。

    输入描述:

    第一行,测试数据组数≤100
    
    第二行,每组测试数据,执行的步数 n ≤ 2000 
    
    然后 n 行 
    
    B x y 
    
    W x y 
    
    (1 ≤ x ≤ 19,1 ≤ y ≤ 19)
    其中,二元组 x,y 表示围棋棋盘上第 x 行第 y 列对应的点。
    输入数据保证是黑白轮流下的。

    输出描述:

    多行
    对于miss的情况,输出是哪一种错误格式,其中:
    miss 1 表示下的位置已经有棋了
    miss 2 表示违反规则6
    miss 3 表示违反规则7
    对于正常的操作,不用输出。
    最后输出最终盘面。“B表示黑子,W表示白子,如果是空点的话,就输出'.'字符。”

    示例1

    输入

    1. 1
    2. 12
    3. B 1 3
    4. W 1 2
    5. B 2 4
    6. W 2 1
    7. B 1 1
    8. W 2 3
    9. B 3 3
    10. W 3 2
    11. B 1 1
    12. W 2 3
    13. B 2 2
    14. W 2 3

    输出

    1. miss 2
    2. miss 2
    3. miss 1
    4. miss 3
    5. .WB................
    6. WB.B...............
    7. .WB................
    8. ...................
    9. ...................
    10. ...................
    11. ...................
    12. ...................
    13. ...................
    14. ...................
    15. ...................
    16. ...................
    17. ...................
    18. ...................
    19. ...................
    20. ...................
    21. ...................
    22. ...................
    23. ...................

    思路 

    一道模拟题。

    模拟题重在如何实现,接下来挑出几个难以实现的地方说一说:

    1. 判断死活。

    对于一块棋,有「气」就能活,没有「气」就会死。下面的 bool live(int, int, char) 处理了这个过程:

    • 从一块棋的某个点开始找联通快,只有与自己相同的点才能相连。
    • 另外,如果超出边界,按照围棋规则不算「气」;如果碰到不同色棋子,按照围棋规则同样也不算「气」。
    • 如果碰到 . 就代表找到了至少一口气,就是暂时活棋。
    1. 落子。

    考虑到围棋还有一个落子问题,也就是说不一定是落子之后自己没有「气」就会死,而是对方有「气」并且自己没有才会死。

    这里采用的判断方法也很巧妙:

    • 首先落下这颗子;
    • 然后判断自己有没有气;
    • 然后判断自己 四联通 的异色棋子会不会死;

    如果自己可以“提”走别人,自己一定不会死(给我留出了「气」),如果自己提不走别人,别人堵住了我所有的「气」,我就会死。

    1. 哈希。

    对于不能发生相同局面,这里可以考虑与 2. 难点建立联系,建立两个数组,一个是试错数组 now,另一个用于保存我之前的答案 old

    如果这里的数组 now 经过哈希之后有重复,就让 now ←\leftarrow← old,如果上述判断都没有问题,就让 old ←\leftarrow← now

    判断局面是否相同,直接哈希并把它扔到 set 里面判重一下就好了,这里采用的是双哈希,碰撞概率非常低。

     AC

    1. #include
    2. #include
    3. #include
    4. int init(){
    5. char c = getchar();
    6. int x = 0, f = 1;
    7. for (; c < '0' || c > '9'; c = getchar())
    8. if (c == '-') f = -1;
    9. for (; c >= '0' && c <= '9'; c = getchar())
    10. x = (x << 1) + (x << 3) + (c ^ 48);
    11. return x * f;
    12. }
    13. void print(int x){
    14. if (x < 0) x = -x, putchar('-');
    15. if (x > 9) print(x / 10);
    16. putchar(x % 10 + '0');
    17. }
    18. const int N = (int) 2e1, dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
    19. const int Buff1 = 131, Buff2 = 171, Mod1 = 998244353, Mod2 = (int) 1e9 + 7;
    20. char now[N][N], old[N][N];
    21. void work(bool tp){
    22. for (int i = 1; i < N; ++i)
    23. for (int j = 1; j < N; ++j)
    24. if (tp) old[i][j] = now[i][j];
    25. else now[i][j] = old[i][j];
    26. }
    27. int go(char ch){
    28. if (ch == 'W') return 0;
    29. if (ch == 'B') return 1;
    30. return 2;
    31. }
    32. std::pair<int, int> Hash(){
    33. int s1 = 0, s2 = 0;
    34. for (int i = 1; i < N; ++i)
    35. for (int j = 1; j < N; ++j)
    36. s1 = (s1 * 1ll * Buff1 + go(now[i][j])) % Mod1,
    37. s2 = (s2 * 1ll * Buff2 + go(now[i][j])) % Mod2;
    38. return std::make_pair(s1, s2);
    39. }
    40. std::setint, int> >set;
    41. bool vis[N][N];
    42. bool live(int x, int y, char ch){
    43. if (now[x][y] == '.') return 1;
    44. if (now[x][y] != ch) return 0;
    45. bool ans = 0; vis[x][y] = 1;
    46. for (int k = 0; k < 4; ++k) {
    47. int nx = x + dx[k], ny = y + dy[k];
    48. if (nx < 1 || nx >= N || ny < 1 || ny >= N) continue;
    49. if (!vis[nx][ny]) ans |= live(nx, ny, ch);
    50. }
    51. return ans;
    52. }
    53. void clean(int x, int y, char ch){
    54. now[x][y] = '.';
    55. for (int k = 0; k < 4; ++k) {
    56. int nx = x + dx[k], ny = y + dy[k];
    57. if (nx < 1 || nx >= N || ny < 1 || ny >= N) continue;
    58. if (now[nx][ny] == ch) clean(nx, ny, ch);
    59. }
    60. }
    61. int chk(char ch, int x, int y){
    62. if (now[x][y] != '.') return 1;
    63. now[x][y] = ch; vis[x][y] = 1;
    64. bool ans = live(x, y, ch);
    65. for (int k = 0; k < 4; ++k) {
    66. int nx = x + dx[k], ny = y + dy[k];
    67. if (!vis[nx][ny] && now[nx][ny] == 'W' + 'B' - ch && !live(nx, ny, 'W' + 'B' - ch))
    68. ans |= 1, clean(nx, ny, 'W' + 'B' - ch);
    69. }
    70. if (!ans) return 2;
    71. if (set.count(Hash())) return 3;
    72. return 0;
    73. }
    74. void Print(const char*str){
    75. for (int i = 0; str[i]; ++i)
    76. putchar(str[i]);
    77. }
    78. int main(){
    79. int T = init();
    80. while (T--) {
    81. set.clear();
    82. for (int i = 1; i < N; ++i)
    83. for (int j = 1; j < N; ++j)
    84. now[i][j] = old[i][j] = '.';
    85. int n = init();
    86. for (int i = 1; i <= n; ++i) {
    87. memset(vis, 0, sizeof(vis));
    88. char ch = 0;
    89. while (ch != 'B' && ch != 'W')
    90. ch = getchar();
    91. int x = init(), y = init();
    92. int tp = chk(ch, x, y);
    93. if (tp) Print("miss "), print(tp), putchar('\n');
    94. else set.insert(Hash());
    95. work(!tp);
    96. }
    97. for (int i = 1; i < N; ++i, putchar('\n'))
    98. for (int j = 1; j < N; ++j)
    99. putchar(now[i][j]);
    100. }
    101. }

  • 相关阅读:
    2022-2028全球COB摄影灯行业调研及趋势分析报告
    vue实现关键字查询列表数据
    winlicense官方版是一款功能专业强大的编程软件
    代码随想录算法训练营第23期day59|503.下一个更大元素II、42. 接雨水
    PL/SQL编程-存储过程
    Kubernetes基础命令
    MySQL主从同步
    102-视频与网络应用篇-环境搭建
    【Rust日报】2023-09-30 使用Rust做web抓取
    大规模 IoT 边缘容器集群管理的几种架构-3-Portainer
  • 原文地址:https://blog.csdn.net/qq_62464995/article/details/126912523