F-Compression CodeForces-1107D (somme des préfixes bidimensionnels)

Insérez la description de l'image iciInsérez la description de l'image ici
La signification de la question: donnez-vous une matrice bidimensionnelle A, et demandez la valeur maximale de x lorsque les conditions sont remplies ;
assurez-vous de noter que la matrice bidimensionnelle B est une matrice compressée. Pourquoi dites-vous cela : Par
exemple:
8 8 matrice, puis lorsque x = 2:
1. Lorsque B [1] [1], i = 1
, j = 1 * 2, donc la valeur de i est 1 et la valeur de j est 1 , donc:
Insérez la description de l'image ici
2. Quand Quand B [1] [2], la plage de valeurs de i est 1,2, et la plage de valeurs de j est 3,4. Donc: on
Insérez la description de l'image ici
peut trouver qu'un élément B [] [] correspond à une petite matrice dans A; et à cause de B Il n'y a que deux valeurs de 0 et 1, ce qui signifie que les valeurs internes de la petite matrice de A correspondant aux éléments de B sont toutes 0 ou toutes 1, donc ce problème peut être transformé en utilisant le préfixe puis le bloc Just cite; la
complexité temporelle est o (n ^ 2);
code AC:

#include<bits/stdc++.h>
using namespace std;
int n;
string s;
int sum[5205][5205];
int main(){
    
    
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
    
    
		 cin>>s;
		 for(int j=0;j<s.length();j++){
    
    
		 	  if(s[j]<='9'&&s[j]>='0'){
    
    
		 	  	   int t=s[j]-'0';
		 	  	   for(int k=j*4+1,y=3;y>=0;k++,y--){
    
    //位移来判断是否为1 这里是顺着来的  就是注意下标 
		 	  	   	    if((t>>y)&1)sum[i][k]=1;
		 	  	   	    else sum[i][k]=0;
					  }
			   }else if(s[j]<='F'&&s[j]>='A'){
    
    
			   	  int  t=s[j]-'A'+10;
			   	    for(int k=j*4+1,y=3;y>=0;k++,y--){
    
    
		 	  	   	    if((t>>y)&1)sum[i][k]=1;
		 	  	   	    else sum[i][k]=0;
					  }
			   }
		 }
	}
	for(int i=1;i<=n;i++){
    
    //二维前缀和 
		  for(int j=1;j<=n;j++){
    
    
		  	    sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
		  	  
		  }
	
	}
	int ans=0;
	for(int i=n;i>=1;i--){
    
    
		  if(n%i==0){
    
    //整除的原因是由于B[i/x][j/x],分段的结果 比如:x==2时,那么i就只能取值1,2,j只能取值1,2;如果x==3,那么i取值1,2,3,j取值为1,2,3 
		  	  int num1=0;
		  	  int num2=0;
		  	 for(int j=i;j<=n;j+=i){
    
    //遍历每一块的前缀和 
		  	 	   for(int k=i;k<=n;k+=i){
    
    
		  	 	   	      if(sum[j][k]-sum[j-i][k]-sum[j][k-i]+sum[j-i][k-i]==0)num1++;
		  	 	   	      else if(sum[j][k]-sum[j-i][k]-sum[j][k-i]+sum[j-i][k-i]==i*i)num2++;
					  }
			   }
			   int tt=n/i;//一个分为了 这么多块 
			   if(num1+num2==tt*tt){
    
    
			        ans=i;break; 	   
			   }
		  }
		  
	}
    printf("%d\n",ans);
	return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_44555205/article/details/104333623
conseillé
Classement