• 2021年中国大学生程序设计竞赛女生专场-F. 地图压缩


    这一题在我初入ACM的时候集训队的学长曾经讲过。正好拿来复习一下KMP和哈希。

    题意

    一个n*n的地图。q次询问给出一个范围,求该范围内最小循环的部分。

    思路

    显然,这个二维地图横向与纵向之间的循环情况是互不影响,最小面积只需要分别求出横向与纵向后相乘即可。

    那么寻找最小循环节的方法就是利用KMP算法了。而对于行和列的预处理只需要用的哈希算法即可。这一题给我的感觉是在于对这两个字符串算法的理解程度,等这篇题解写完之后我应该会来详细写写这两个字符串算法。

    代码

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #define Endl "\n"
    13. using namespace std;
    14. typedef long long ll;
    15. typedef pair<int,int> pii;
    16. const int maxn = 2000007;
    17. const int INF = 0x3f3f3f;
    18. const int mod = 1e9 + 7;
    19. const double pi = acos(-1);
    20. inline ll read(){
    21. ll x = 0, f = 1; char ch; ch = getchar();
    22. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    23. while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    24. return x*f;
    25. }
    26. const int base=131;
    27. ll n,q;
    28. ll power[2050];
    29. char mp[2050][2050];
    30. ll hashc[2050][2050],hashr[2050][2050];
    31. int nxt[2050];
    32. ll a[2050];
    33. int kmp(int len)
    34. {
    35. memset(nxt,0,sizeof(nxt));
    36. int j=0;
    37. for(int i=2;i<=len;i++)
    38. {
    39. while(j!=0&&a[i]!=a[j+1])
    40. j=nxt[j];
    41. if(a[i]==a[j+1])
    42. j++;
    43. nxt[i]=j;
    44. }
    45. return len-nxt[len];
    46. }
    47. void solve()
    48. {
    49. n=read(),q=read();
    50. power[0]=1;
    51. for(int i=1;i<=n;i++)
    52. power[i]=power[i-1]*base%mod;
    53. for(int i=1;i<=n;i++)
    54. cin>>(mp[i]+1);
    55. for(int i=1;i<=n;i++)
    56. for(int j=1;j<=n;j++)
    57. hashr[i][j]=(hashr[i][j-1]*base%mod+(mp[i][j]-'a'+1))%mod;
    58. for(int j=1;j<=n;j++)
    59. for(int i=1;i<=n;i++)
    60. hashc[i][j]=(hashc[i-1][j]*base%mod+(mp[i][j]-'a'+1))%mod;
    61. while(q--)
    62. {
    63. int x1,x2,y1,y2;
    64. x1=read(),y1=read(),x2=read(),y2=read();
    65. int cnt=0;
    66. for(int i=x1;i<=x2;i++)
    67. {
    68. a[++cnt]=(hashr[i][y2]-hashr[i][y1-1]*power[y2-y1+1]%mod+mod)%mod;
    69. }
    70. int x=kmp(cnt);
    71. cnt=0;
    72. memset(a,0,sizeof(a));
    73. for(int i=y1;i<=y2;i++)
    74. {
    75. a[++cnt]=(hashc[x2][i]-hashc[x1-1][i]*power[x2-x1+1]%mod+mod)%mod;
    76. }
    77. int y=kmp(cnt);
    78. cout<
    79. }
    80. }
    81. int main() {
    82. //for(int T = read(); T; T--)
    83. solve();
    84. return 0;
    85. }

     

  • 相关阅读:
    python解释def __init__(self, *args, **kwargs)
    极光魔链(JMLink)使用教程
    java-springmvc 01
    Vue项目自动更换BaseUrl
    专为小白打造—Kafka一篇文章从入门到入土
    jetson nano——安装archiconda
    部署WekaFS并行文件系统的10大理由
    Unity-Resources资源同步加载
    管理Java依赖关系的最佳实践
    UML,集合框架
  • 原文地址:https://blog.csdn.net/m0_66624446/article/details/126833945