Diferencia bidimensional de la resta de la matriz de ICPC Xiaomi

Enlace de tema

https://ac.nowcoder.com/acm/contest/7501?&headNav=www#question

Título

Dada una matriz de n * m, puede restar uno de todos los elementos de la matriz pequeña de a * b en la matriz varias veces y preguntar si se puede reducir a 0.

Ideas

Recorra cada elemento de arriba a abajo y de izquierda a derecha. Para el valor actual ai de cada elemento, todas las matrices a * b de la primera fila y la primera columna se restarán de ai. Una vez completado el recorrido, si todos los valores son Cero significa que se puede lograr; de lo contrario, no.

La complejidad del algoritmo de fuerza bruta es O (nmab), podemos usar el intervalo de optimización de diferencia bidimensional para modificar.

Diferencia unidimensional diff [i] = a [i] -a [i-1], agregue z al intervalo x, y, puede diff [x] + = z, diff [y + 1] - = z. Finalmente La suma del prefijo es la matriz original.

Diferencia bidimensional diff [i] [j] = a [i] [j] -a [i-1] [j] -a [i] [j-1] + a [i-1] [j-1] , Si se suma z al rectángulo x1 y1, x2 y2, entonces diff [x1] [y1] + = z, diff [x1] [y2 + 1] - = z, diff [x2 + 1] [y1] - = z, diff [x2 + 1] [y2 + 1] + = z. La matriz original puede usar un prefijo bidimensional y restaurar.

Reducimos los elementos de la matriz a 0, y la matriz de diferencias son todos ceros. Luego, atravesamos la matriz de diferencias. Si el elemento actual es mayor o igual que 0, el rectángulo pequeño con este punto como la primera fila y la primera columna se usa para la resta de intervalo usando la matriz de diferencias De lo contrario, se determina que la respuesta no existe.

Código

#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<string>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib> 
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
//#define int long long
//#define double long double
using namespace std;
	typedef long long ll;
	const int maxn=4005;
	const int inf=0x3f3f3f3f;
	int n,m,a,b;
	int aa[maxn][maxn];
	int diff[maxn][maxn];
	int main(){
    
    
		IOS
		int tn;
		cin>>tn;
		while(tn--){
    
    
			cin>>n>>m>>a>>b;
			for(int i=1;i<=n;i++)
				for(int j=1;j<=m;j++){
    
    
					cin>>aa[i][j];
		            diff[i][j]=aa[i][j]-aa[i-1][j]-aa[i][j-1]+aa[i-1][j-1];
				}
			bool bl=1;
			for(int i=1;i<=n;i++){
    
    
				for(int j=1;j<=m;j++){
    
    
            		int tmp=diff[i][j];
            		if(!tmp)
            			continue;
            		else if(tmp<0){
    
    
            			bl=0;
            			break;
					}
					else if(i<=n-a+1&&j<=m-b+1){
    
    
						diff[i][j] -= tmp;
						diff[i][j+b] +=tmp;
						diff[i+a][j] +=tmp;
						diff[i+a][j+b] -= tmp;
					}	
					else{
    
    
						bl=0;
						break;
					}
				}
			}
			if(!bl)
				cout<<"QAQ"<<endl;
			
			else
				cout<<"^_^"<<endl;
			
			
		}
	}

Supongo que te gusta

Origin blog.csdn.net/TheSunspot/article/details/109275445
Recomendado
Clasificación