poj3274
这道题做得坎坷啊,刚开始没注意看hint,硬生生地一直看不懂题意。
好不容易看懂题目后也没什么思路。参看别人的思路后了下面巨丑无比的代码,懒得改了。
这道理给我的收获就是,有些题目不能急,是需要先用数学推理一些等价关系后才会知道该用什么算法的。
思路:sum[i][j]前i头牛的feature的总数。
sum[a][j]-sum[b][j]=sum[a][j-1]-sum[b][j-1].....=sum[a][0]-sum[b][0]
求出a b的差即可。
上式再转化:sum[a][j]-sum[a][j-1]=sum[b][j]-sum[b][j-1]......
设c[i][j]=sum[i][j]-sum[i][0];
c[a][j]==c[b][j]
然后对c[i]数组哈希,求出最大的b-a即可。
Source Code
Problem: 3274 | User: 64162451 | |
Memory: 39120K | Time: 875MS | |
Language: C++ | Result: Accepted |
- Source Code
#include<iostream> #include<vector> #include<fstream> using namespace std; const int prime=14997; const int N=100010; const int K=32; int n,k; int cow[N][K]; int sum[N][K]; int c[N+1][K]; int csum[N+1]; vector<int> hash1[prime]; bool cmp(int a,int b) { for(int i=0;i<k;i++) if(c[a][i]!=c[b][i]) return false; return true; } int main() { //fstream cin("C:\\Users\\wuyanyisb\\Desktop\\1.txt"); cin>>n>>k; int in; for(int i=0;i<n;i++) { cin>>in; for(int j=k-1;j>=0;j--) { cow[i][j]=in%2; in/=2; } } memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) for(int j=0;j<k;j++) if(cow[i-1][j]==1) sum[i][j]=sum[i-1][j]+1; else sum[i][j]=sum[i-1][j]; for(int i=1;i<=n;i++) for(int j=0;j<k;j++) { c[i][j]=sum[i][j]-sum[i][0]; csum[i]+=(c[i][j]); } for(int i=0;i<=n;i++) hash1[abs(csum[i])%prime].push_back(i); int ans=0; for(int i=0;i<prime;i++) for(int j1=0;j1<hash1[i].size();j1++) for(int j2=j1+1;j2<hash1[i].size();j2++) if(cmp(hash1[i][j1],hash1[i][j2])) { if(ans<abs(hash1[i][j1]-hash1[i][j2])) ans=abs(hash1[i][j1]-hash1[i][j2]); } cout<<ans<<endl; system("pause"); return 0; }