1 条题解
-
0
自动搬运
来自洛谷,原作者为

cfkk
一入OI深似海,从此AC是路人搬运于
2025-08-24 22:21:24,当前版本为作者最后更新于2021-12-11 22:29:46,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
这道题可以用哈希来做,因为 n 和 m 的范围比较大,还需要二分和前缀和寻找答案。
但是输入是是行在前,求哈希是要列在前,需要转换。
求哈希需要用到 Ascii 码,但是 Ascii 中有很多浪费的元素,所以将 Ascii 的 256 为改成 131 位是容错率最小的。
所以哈希数组的转换公式为:
= × 131+
与大家不同的是,我用的是单哈希,别人是双哈希。
#include<bits/stdc++.h> using namespace std; char c[5005][5005];//原方阵 int n,m; unsigned long long has[5005][5005],data[5005];//防止爆内存 bool check(int mid) { for(int i=1;i<=m;i++){data[i]=has[i][n-mid];}//把哈希转换到每一列 sort(data+1,data+m+1);//从小到大排序 for(int i=2;i<=m;i++) { if(data[i]==data[i-1]){return 0;}//排序后如果相邻两个相同,就不是正确答案 } return 1; } int main() { cin>>n>>m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++){cin>>c[i][j];} } for(int j=1;j<=m;j++)//因为是判断列,所以把列放在前面 { for(int i=n;i>0;i--) { has[j][n-i+1]=has[j][n-i]*131+c[i][j];//哈希转换 } } int l=0,r=n-1; while(l<r)//二分 { int mid=(l+r+1)/2;//如果是(l+r)/2会死循环 if(check(mid)){l=mid;}//判断check else{r=mid-1;} } cout<<l<<endl; return 0; }
- 1
信息
- ID
- 5529
- 时间
- 1000ms
- 内存
- 32MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者