题解:Codeforces Round 960 (Div. 2) D

D. Grid Puzzle

time limit per test: 2 seconds

memory limit per test: 256 megabytes

input: standard input

output: standard output

You are given an array a a a of size n n n.

There is an n × n n \times n n×n grid. In the i i i-th row, the first a i a_i ai cells are black and the other cells are white. In other words, note ( i , j ) (i,j) (i,j) as the cell in the i i i-th row and j j j-th column, cells ( i , 1 ) , ( i , 2 ) , … , ( i , a i ) (i,1), (i,2), \ldots, (i,a_i) (i,1),(i,2),,(i,ai) are black, and cells ( i , a i + 1 ) , … , ( i , n ) (i,a_i+1), \ldots, (i,n) (i,ai+1),,(i,n) are white.

You can do the following operations any number of times in any order:

  • Dye a 2 × 2 2 \times 2 2×2 subgrid white;
  • Dye a whole row white. Note you can not dye a whole column white.

Find the minimum number of operations to dye all cells white.

给你一个大小为 n n n 的数组 a a a

其中有一个 n × n n \times n n×n 网格。在第 i i i 行中,第一个 a i a_i ai 单元格为黑色,其他单元格为白色。换句话说,注意 ( i , j ) (i,j) (i,j)是第 i i i 行和第 j j j 列中的单元格, ( i , 1 ) , ( i , 2 ) , … , ( i , a i ) (i,1), (i,2), \ldots, (i,a_i) (i,1),(i,2),,(i,ai) 单元格是黑色的, ( i , a i + 1 ) , … , ( i , n ) (i,a_{i+1}), \ldots, (i,n) (i,ai+1),,(i,n) 单元格是白色的。

您可以按照任意顺序多次进行以下操作:

  • 将一个 2 × 2 2 \times 2 2×2 子网格染成白色;
  • 将整行染白。注意不能将整列染白。

找出将所有单元格染白的最少操作次数。

Input

The first line contains an integer t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1t104) — the number of test cases.

For each test case:

  • The first line contains an integer n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \leq n \leq 2 \cdot 10^5 1n2105) — the size of the array a a a.
  • The second line contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an ( 0 ≤ a i ≤ n 0 \leq a_i \leq n 0ain).

It’s guaranteed that the sum of n n n over all test cases will not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2105.

输入

第一行包含一个整数 t t t 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1t104 )。( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1t104 ) - 测试用例的数量。

对于每个测试用例

  • 第一行包含一个整数 n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \leq n \leq 2 \cdot 10^5 1n2105 ) - 数组的大小 a a a
  • 第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an ( 0 ≤ a i ≤ n 0 \leq a_i \leq n 0ain )。

保证所有测试用例中 n n n 的总和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2105

Output

For each test case, output a single integer — the minimum number of operations to dye all cells white.

输出

对于每个测试用例,输出一个整数 —— 将所有单元格染白的最少操作次数。

Example

input

10
1
0
4
2 4 4 2
4
3 2 1 0
3
0 3 0
3
0 1 3
3
3 1 0
4
3 1 0 3
4
0 2 2 2
6
1 3 4 2 0 4
8
2 2 5 2 3 4 2 4

output

0
3
2
1
2
2
3
2
4
6

Note

In the first test case, you don’t need to do any operation.

In the second test case, you can do:

  • Dye ( 1 , 1 ) , ( 1 , 2 ) , ( 2 , 1 ) (1,1), (1,2), (2,1) (1,1),(1,2),(2,1), and ( 2 , 2 ) (2,2) (2,2) white;
  • Dye ( 2 , 3 ) , ( 2 , 4 ) , ( 3 , 3 ) (2,3), (2,4), (3,3) (2,3),(2,4),(3,3), and ( 3 , 4 ) (3,4) (3,4) white;
  • Dye ( 3 , 1 ) , ( 3 , 2 ) , ( 4 , 1 ) (3,1), (3,2), (4,1) (3,1),(3,2),(4,1), and ( 4 , 2 ) (4,2) (4,2) white.

It can be proven 3 3 3 is the minimum number of operations.

In the third test case, you can do:

  • Dye the first row white;
  • Dye ( 2 , 1 ) , ( 2 , 2 ) , ( 3 , 1 ) (2,1), (2,2), (3,1) (2,1),(2,2),(3,1), and ( 3 , 2 ) (3,2) (3,2) white.

It can be proven 2 2 2 is the minimum number of operations.

在第一个测试案例中,您不需要进行任何操作。

在第二个测试用例中,您可以进行以下操作:

  • ( 1 , 1 ) , ( 1 , 2 ) , ( 2 , 1 ) (1,1), (1,2), (2,1) (1,1),(1,2),(2,1) ( 2 , 2 ) (2,2) (2,2) 白色;
  • ( 2 , 3 ) , ( 2 , 4 ) , ( 3 , 3 ) (2,3), (2,4), (3,3) (2,3),(2,4),(3,3) ( 3 , 4 ) (3,4) (3,4) 白色;
  • ( 3 , 1 ) , ( 3 , 2 ) , ( 4 , 1 ) (3,1), (3,2), (4,1) (3,1),(3,2),(4,1) ( 4 , 2 ) (4,2) (4,2) 白色。

可以证明 3 3 3 是最少的运算次数。

在第三个测试案例中,你可以这样做:

  • 将第一行染成白色;
  • ( 2 , 1 ) , ( 2 , 2 ) , ( 3 , 1 ) (2,1), (2,2), (3,1) (2,1),(2,2),(3,1) ( 3 , 2 ) (3,2) (3,2) 染成白色。

可以证明 2 2 2 是最少的操作数。

我的题解

提示!以下文字仅代表我的想法
如果有更优的做法欢迎交流讨论

这题是很典型的贪心吧

首先,如果满足消除 2 × 2 2 \times 2 2×2块步骤较少的情况,那么这一行的黑块一定不超过 4 4 4 。因此,我们可以把黑色块数大于 4 4 4 的行处理成 4 4 4 并增加消除步数。(预处理)

其次,我们来处理剩下的块
假设全部用 2 × 2 2 \times 2 2×2 块的消除方法
消除方法

我们先用一个变量 m m m 存储到第 i i i 行时连续用了多少次
再用一个变量 l a s t last last 存储上一行的黑块数量
全部初始化为 0 0 0

我们对第 i i i 行黑块数量 a i a_i ai 进行分类讨论

  1. a i = 0 a_i = 0 ai=0
    • 假如 m e m mem mem 不为 0 0 0,也就是说前面用的是 2 × 2 2 \times 2 2×2 块的消除方法,那就要判断前面的消除方法能不能正好全部消除前面的黑块(我们只用判断最后一个就可以了)
      • 假如上一块的黑块数量是 4 4 4,那么是无论如何都不能完全消除的,所以要再用一次消除整行的方法把上一行清除(想知道为什么看上图消除方法)
      • 假如上一块的黑块数量是 2 2 2,判断 m e m mem mem 是奇数还是偶数:如果是奇数,那就可以完美消除,要减去 1 1 1 再加到 s u m sum sum 里面,但是 m e m − 1 mem - 1 mem1 不能小于 1 1 1;如果是偶数,就不是完美消除,不需要减 1 1 1 。(想知道为什么看上图消除方法)
    • 如果 m e m mem mem 0 0 0 ,continue就好了。
  2. 0 < a i ≤ 2 0 \lt a_i \le 2 0<ai2
    • 假如 m e m mem mem 0 0 0,直接 m e m mem mem++ 就好了。

    • 假如 m e m mem mem 不为 0 0 0 ,看下一步能不能消除到这一行,也就是判断 m e m mem mem 是奇数还是偶数

      • 假如 m e m mem mem 是奇数 ,那么下一个 m e m mem mem 是偶数,那就不能覆盖这一个行,因此把前面的 m e m mem mem 加到 s u m sum sum 里面去再加 1 1 1,然后 m e m mem mem 从该行重新开始计算(或者说给前面一块(一定是大于2的)用一次消除一整行的操作,把没有消除的消除掉。如下图,我认为第二种是比第一种更贪的,因为下一块的黑块有可能不大于2->浪费掉了)
        rt

      • 假如 m e m mem mem 是偶数 ,那么下一个 m e m mem mem 是奇数,前面一块刚好完美消除掉黑块,因此可以直接接着算(虽然我是重新计算然后 m e m = 1 mem = 1 mem=1 的,但是大差不差)

  3. 2 < a i ≤ 4 2 \lt a_i \le 4 2<ai4
    • 假如 m e m mem mem 等于 0 0 0 的话,不足以实现 2 × 2 2 \times 2 2×2 块的消除方法,因此直接用消除一整行的方法, s u m sum sum ++。
    • 假如 m e m mem mem 不等于 0 0 0,直接 m e m mem mem ++就可以了

退出循环后再处理一下mem就好了。

我的代码

#include <bits/stdc++.h>
#define int long long

const int N = 1e7 + 10;
int t;
int a[N];

void solve() {
    int sum = 0;
    int mem = 0;
    int last = 0;
    int n;
    std::cin >> n;

    for(int i = 0 ; i < n ; i ++) {
        std::cin >> a[i];
        if(a[i] > 4) {
            sum ++;
            a[i] = 0;
        }
    }

    for(int i = 0 ; i < n ; i ++) {
        if(a[i] == 0) {
            if(mem) {
                if(last <= 2 && mem & 1) sum += std::max(mem -1,(int)1);
                else sum += mem;
            }
            mem = 0;
        }
        else if(a[i] <= 2) {
            if(mem) {
                sum += mem;
                mem = (mem & 1 ? 0 : 1);
            }
            else mem ++;
        }
        else {
            if(mem) mem ++;
            else sum ++;
        }
        last = a[i];
    }

    if(mem) {
        if(last > 2 || !(mem & 1)) sum += mem;
        else sum += std::max(mem - 1,(int)1);
    }

    std::cout << sum << "\n";
}

signed main() {
    std::cin >> t;
    while(t--) {
        solve();
    }
    return 0;
}

搬运自https://www.cnblogs.com/jiejiejiang2004/p/18314425
博主已同意,我就是博主

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,根据提供的引用内容,我无法理解你具体想要问什么问题。请提供更清晰明确的问题,我将竭诚为你解答。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Codeforces Round 860 (Div. 2)题解](https://blog.csdn.net/qq_60653991/article/details/129802687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【CodeforcesCodeforces Round 865 (Div. 2) (补赛)](https://blog.csdn.net/t_mod/article/details/130104033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Codeforces Round 872 (Div. 2)(前三道](https://blog.csdn.net/qq_68286180/article/details/130570952)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值