D. Matrix Cascade (the structure records the impact of the front on the back)

Problem - D - Codeforces

There is a matrix of size n×n, consisting of 0s and 1s. Rows are numbered 1 to n from top to bottom, and columns are numbered 1 to n from left to right. The intersection point (x,y) represents the cell in the xth row and yth column.

AquaMoon wants to change all elements of the matrix to 0. In one step, she can do the following:

 
 

Plain Text

 
 
选择一个任意的单元格,假设为(i,j),然后翻转(i,j)中的元素,并翻转(x,y)中的所有元素,其中x>i且x−i≥|y−j|。翻转一个值意味着将其改变为相反值:0变为1,1变为0。

Help AquaMoon determine the minimum number of steps she needs to perform to change all elements of the matrix to 0. We can prove that the answer always exists. enter

Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤105). Next is the description of the test case.

The first line of each test case contains an integer n (2≤n≤3000).

The i-th of the next n lines contains a binary string containing only the characters 0 and 1, with length n.

Ensure that the sum of n2 in all test cases does not exceed 9000000. output

For each test case, print the minimum number of steps. Example input copy

3
5
00100
01110
11111
11111
11111
3
100
110
110
6
010101
111101
011110
000000
111010
001110

output copy

1

2

15

Notice

In the first test case we can use the following scenario:

 
 

Plain Text

 
 
在单元格(1,3)上执行操作。

Obviously, the elements of the initial matrix are not all 0, so at least one operation is required. Therefore, the answer is 1.

In the second test case, we use the following scenario:

 
 

Plain Text

 
 
在单元格(3,3)上执行操作;
在单元格(1,1)上执行操作。

It can be shown that all elements cannot be converted to 0 in 0 or 1 steps, so the answer is exactly 2.

answer:

A very interesting question, and the meaning of the question is easy to understand. If you operate a point, it will be inverted in the next fan wave range. The optimal is definitely from top to bottom. If it is 1, operate it, but you may operate it many times. , there are many points, so it is difficult to determine the current status.

We use a structure to record the status of a point

val represents the initial 0 or 1

u represents how many waves this point is under the influence of at this time. If this point is under the influence of some waves at this time, then the point directly below is also under the influence of those waves.

l, r means that each wave will not only propagate downward, but also propagate to the lower left and lower right. Therefore, recording each point will propagate to the lower left for several waves, and propagate to the lower right for several waves, and then assign these two attributes to the points at the lower left/lower right of the point, and update the u of the propagated point at the same time: Since These points are affected by some additional waves, so the number of waves affecting that point will naturally increase by the number of these waves.

Each point val += u of this point at this time, if %2 == 1, operation is required

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> PII;
const int N = 5e5 + 10;
struct node
{
	int val;
	int u;
	int l,r;
}a[3004][3004];
void solve()
{
	int n;
	cin >> n;
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= n;j++)
		{
			char c;
			cin >> c;
			a[i][j] = {0};
			a[i][j].val = c - '0';
		}
	}
	int ans = 0;
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= n;j++)
		{
			a[i][j].val += a[i][j].u;
			if(a[i][j].val%2 == 1)
			{
				ans++;
				a[i][j].u ++;
				a[i][j].l++;
				a[i][j].r++;
			}
			
			a[i + 1][j].u += a[i][j].u;
			
			a[i + 1][j - 1].l += a[i][j].l;
			a[i + 1][j - 1].u += a[i][j].l;
			
			a[i + 1][j + 1].r += a[i][j].r;
			a[i + 1][j + 1].u += a[i][j].r;
		}
	}
	cout << ans <<"\n";
} 
//111011
signed main()
{
	int t = 1;
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> t ;	
	while(t--)
	{
		solve();
	}
}
//环

Guess you like

Origin blog.csdn.net/m0_64158084/article/details/132844612