• 【二维差分】ICPC南京 A


    https://codeforces.com/gym/104128/problem/A

    题意

     

    思路

    二维差分+经典模型

    考虑如果没有洞那么经历操作之后会剩下什么样子的袋鼠。发现上下左右移动可以看成是边界在移动,边界一直保持一个原初的矩形形状,而且上下移动和左右移动没有任何关系。一旦边界移动到了一个位置,这个位置前面的袋鼠都会消失。

    所以记录u,d,l,r,表示在移动时所产生的最小矩阵的上下左右边界,这样剩下的袋鼠数量就是有(d-u+1)*(r-l+1)个。

    加入有洞的情况,发现洞产生的路径都可以通过平移获得,那么就只维护一条路径,就是从(0,0)点开始的路径,那么所有的点(i,j)的路径就是(0,0)点开始的路径上的点加(i,j)。 那么我们要维护有洞会让袋鼠消失多少,只有在u<=x<=d,l<=y<=r的才是有效被消失的袋鼠,那么就维护mp[i][j]表示从(i,j)点开始会让多少只袋鼠消失,发现对于点(x,y),只会对一个矩形内的数加1,左上角为(u-x,l-y),右下角为(d-x,r-y)的矩形,变成二维差分维护,那么在二维差分中给一个点加1等于给它往右往下的全部点加1.

    注意:要去除经过的重复的点,重复点不能重复计算答案,因为他们去除的是同一片袋鼠。

    Code:

    1. #include
    2. constexpr int N = 1e3 + 10;
    3. constexpr int mod = 998244353;
    4. constexpr int Inf = 0x3f3f3f3f;
    5. std::string s;
    6. int n, m, k;
    7. int f[N][N];
    8. int vis[N][N];
    9. void add(int x1, int y1, int x2, int y2) {
    10. f[x1][y1] ++;
    11. f[x2 + 1][y1] --;
    12. f[x1][y2 + 1] --;
    13. f[x2 + 1][y2 + 1] ++;
    14. }
    15. void solve() {
    16. std::cin >> n >> m >> k;
    17. for (int i = 0; i <= n + 5; i ++) {
    18. for (int j = 0; j <= m + 5; j ++) {
    19. vis[i][j] = f[i][j] = 0;
    20. }
    21. }
    22. std::cin >> s;
    23. int sz = s.size();
    24. s = " " + s;
    25. int u = 1, d = n, l = 1, r = m;
    26. int U = 1, D = n, L = 1, R = m;
    27. for (int i = 1; i <= sz; i ++) {
    28. if (s[i] == 'U') {
    29. u ++;
    30. d ++;
    31. }else if (s[i] == 'D') {
    32. u --;
    33. d --;
    34. }else if (s[i] == 'L') {
    35. l ++;
    36. r ++;
    37. }else {
    38. l --;
    39. r --;
    40. }
    41. U = std::max(U, u);
    42. D = std::min(D, d);
    43. L = std::max(L, l);
    44. R = std::min(R, r);
    45. }
    46. if (L > R || U > D) {
    47. if (k) {
    48. std::cout << 0 << "\n";
    49. }else {
    50. std::cout << n * m << "\n";
    51. }
    52. return;
    53. }
    54. int del = (R - L + 1) * (D - U + 1) - k;
    55. if (del < 0) {
    56. std::cout << 0 << "\n";
    57. return;
    58. }
    59. add(U, L, D, R);
    60. vis[L][U] = 1;
    61. for (int i = 1; i <= sz; i ++) {
    62. if (s[i] == 'L') {
    63. L --;
    64. R --;
    65. }else if (s[i] == 'R') {
    66. L ++;
    67. R ++;
    68. }else if (s[i] == 'U') {
    69. U --;
    70. D --;
    71. }else {
    72. U ++;
    73. D ++;
    74. }
    75. if (vis[L][U]) continue;
    76. vis[L][U] = 1;
    77. add(U, L, D, R);
    78. }
    79. for (int i = 1; i <= n; i ++) {
    80. for (int j = 1; j <= m; j ++) {
    81. f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];
    82. }
    83. }
    84. int ans = 0;
    85. for (int i = 1; i <= n; i ++) {
    86. for (int j = 1; j <= m; j ++) {
    87. if (f[i][j] == del) ans ++;
    88. }
    89. }
    90. std::cout << ans << "\n";
    91. }
    92. signed main() {
    93. std::ios::sync_with_stdio(false);
    94. std::cin.tie(nullptr);
    95. int t = 1;
    96. std::cin >> t;
    97. while (t--) {
    98. solve();
    99. }
    100. return 0;
    101. }

     

  • 相关阅读:
    CSS3 中 transition 和 animation 的属性分别有哪些
    Rocky9.2根目录满了如何扩容根目录
    Vue实现手机端界面的购物车案例
    C++ 四种类型转换
    在CentOS 7中手工打造和运行xml文件配置的Servlet,然后使用curl、浏览器、telnet等三种工具各自测试
    Java开发者必备:支付宝沙箱环境支付远程调试指南
    python简单实现网络爬虫
    计算机毕业设计springboot+vue+elementUI会员制医疗预约服务管理信息系统
    java---jar详解
    【WSN】模拟无线传感器网络研究(Matlab代码实现)
  • 原文地址:https://blog.csdn.net/weixin_62528401/article/details/133968882