• BZOJ1567 [JSOI2008]Blue Mary的战役地图(二分+二维hash)


    题意

    问边长为n的两个正方形中最大的相等子正方形。(n<=50)

    题解

    用到了二维hash,感觉和一维的不太一样。

    对于列行有两个不同的进制数然后也是通过类似前缀和的方法差分出一个矩形的hash值

    这样可以0(1)的算出一个正方形的hash值。

    然后我们二分长度x,每一次遍历整个长度为x的子正方形n2判断即可。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<map>
     7 using namespace std;
     8 const int mod1=38833;
     9 const int mod2=29123;
    10 map<unsigned,int> ma;
    11 unsigned long long pow1[60],pow2[60],hash1[60][60],hash2[60][60];
    12 int n,ans,t;
    13 bool judge(int x){
    14     ++t;
    15     for(int i=x;i<=n;i++)
    16         for(int j=x;j<=n;j++){
    17             ma[hash1[i][j]-hash1[i-x][j]*pow2[x]-hash1[i][j-x]*pow1[x]+hash1[i-x][j-x]*pow1[x]*pow2[x]]=t;
    18         }
    19     for(int i=x;i<=n;i++)
    20         for(int j=x;j<=n;j++){
    21             if(ma[hash2[i][j]-hash2[i-x][j]*pow2[x]-hash2[i][j-x]*pow1[x]+hash2[i-x][j-x]*pow1[x]*pow2[x]]==t)return true;
    22         }
    23     return false;
    24 }
    25 int main(){
    26     scanf("%d",&n);
    27     pow1[0]=pow2[0]=1;
    28     for(int i=1;i<=n;i++){
    29         pow1[i]=pow1[i-1]*mod1;
    30         pow2[i]=pow2[i-1]*mod2;
    31     }
    32     for(int i=1;i<=n;i++)
    33         for(int j=1;j<=n;j++){
    34             int a;
    35             scanf("%d",&a);
    36             hash1[i][j]=hash1[i][j-1]*mod1+a;
    37         }
    38     for(int i=1;i<=n;i++)
    39         for(int j=1;j<=n;j++){
    40             int a;
    41             scanf("%d",&a);
    42             hash2[i][j]=hash2[i][j-1]*mod1+a;
    43         }
    44     for(int i=1;i<=n;i++)
    45         for(int j=1;j<=n;j++)
    46             hash1[i][j]=hash1[i-1][j]*mod2+hash1[i][j];
    47     for(int i=1;i<=n;i++)
    48         for(int j=1;j<=n;j++)
    49             hash2[i][j]=hash2[i-1][j]*mod2+hash2[i][j];
    50     int l=1;int r=n;
    51     while(l<=r){
    52         int mid=(l+r)>>1;
    53         if(judge(mid)){
    54             l=mid+1;
    55             ans=mid;
    56         }
    57         else r=mid-1;
    58     }
    59     printf("%d",ans);
    60     return 0;
    61 } 
  • 相关阅读:
    You Will Be Memorizing Things
    PowerShell与cmd
    select的一些问题。
    深刻理解数据库外键含义
    html居中问题
    jsp中嵌入的html
    jdbc连接mysql报错:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column '金厉旭' in 'field list'
    [kuangbin带你飞]专题一 简单搜索
    算法竞赛训练指南11.2 最小生成树
    [kuangbin带你飞]专题六 最小生成树
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9546077.html
Copyright © 2020-2023  润新知