HDU-1937 Método de regla 2D de búsqueda de asientos

  • Encontrar asientos
  • Significado de la pregunta
    Encuentra un rectángulo, el número de asientos en el rectángulo debe ser mayor o igual que K, encuentra el área del rectángulo más pequeño que cumple las condiciones
  • Ideas En un
    principio pensé sobre violencia y poda, pero la peor complejidad sigue siendo 1e8, que es decisiva. Más tarde, pensé en el método de la regla, pero este método de la regla es bidimensional y es fácil de escribir siempre que esté ligeramente procesado.
    Atravesamos los límites superior e inferior del rectángulo y luego tomamos la regla para encontrar la solución óptima que satisfaga las condiciones.
    Ejemplo 1
    En la figura, i apunta al límite superior del rectángulo y j apunta al límite inferior. lyr apuntan a columnas. Cuando r se desplaza hacia la derecha, suma + = 3, cuando l se desplaza hacia la derecha, suma- = 1. De acuerdo con la comparación entre suma y K, la dirección del movimiento de l se determina cuando suma <K. Mueva r hacia la derecha; de lo contrario, mueva l hacia la derecha. Para l, r cada desplazamiento del valor de cambio de la suma en una columna, podemos prefijar y sumar cada columna de acuerdo con el espacio, de modo que el valor de cambio se pueda calcular mediante o (1) ( suma [j] [r] - suma [i] [r ] O suma [j] [l] - suma [i] [l] suma [j] [r] -sum [i] [r] o suma [j] [l] -suma [i] [l]s u m [ j ] [ r ]-S U m [ I ] [ R & lt ] o por S U m [ J ] [ L ]-s u m [ i ] [ l ] ). La complejidad de un solo conjunto de ejemplos es o (1e6)
  • Código
#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long ul;
typedef unsigned long long ull;
#define pi acos(-1.0)
#define e exp(1.0)
#define pb push_back
#define mk make_pair
#define fir first
#define sec second
#define scf scanf
#define prf printf
typedef pair<ll,ll> pa;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll MAX_R=360;
char Ma[MAX_R][MAX_R];
ll R,C,K;
ll sum[MAX_R][MAX_R];
int main()
{
    
    
//  freopen(".../.txt","w",stdout);
//  freopen(".../.txt","r",stdin);
	ios::sync_with_stdio(false);
	ll i,j,k,x,y;
	while(cin>>R>>C>>K&&(R||C||K)){
    
    
		for(i=1;i<=R;i++)
		cin>>Ma[i]+1;
		for(j=1;j<=C;j++){
    
    //前缀和预处理
			sum[0][j]=0;
			for(i=1;i<=R;i++){
    
    
				sum[i][j]=sum[i-1][j];
				if(Ma[i][j]=='.')
				sum[i][j]++;
			}
		}
//		cout<<do_(1,1,2,3)<<endl;
		ll ans=INF,l,r;
		for(i=1;i<=R;i++){
    
    
			for(j=i;j<=R;j++){
    
    
				if((j-i+1)>ans)//单列的面积已经比已知答案大了,跳过
				break;
				l=r=1;
				ll tmp=0;
				bool flag=1;
				while(l<=r&&r<=C){
    
    
					if(flag)
					tmp+=(sum[j][r]-sum[i-1][r]);
					if(tmp<K){
    
    
						r++;
						flag=1;
					}
					else{
    
    
						ans=min(ans,(j-i+1)*(r-l+1));
//						cout<<"("<<i<<","<<l<<")"<<"("<<j<<","<<r<<")"<<endl;
						tmp-=(sum[j][l]-sum[i-1][l]);
						l++;
						flag=0;
						if(l>r){
    
    
							r=l;
							flag=1;
						}
					}
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_43311695/article/details/108676249
Recomendado
Clasificación