lightoj1423Olympic Swimming
2015-12-09 23:17
441 查看
思路:有k条长度为l的泳道,每天泳道上面有n[i]个障碍物,w诶了比赛的公平性,每个泳道里面只能有相同数目个障碍物,求最长的泳道。
这样我们可以枚举泳道的右位置,计算出每个泳道中从0到这个位置的障碍物数目,求出最大与最小值。如果相等说明这个位置是目前长的泳道右端点。然后,因为要想等,如果要以这个位置为泳道的右端点,那么我们需要求一个想等的左端点。cnt[i] = A[i][j] - mi;这样的话,障碍物的数目就是mi个,求一个最远的左端点就好了,,,这样就需要hash一下,因为直接找的话时间消耗太大了,这里减了之后就会又一个差值状态,只需要求出这个状态出现的最早的位置就好了,出现过就是端点距离差+1(这里是因为出现了相同的差值状态,说明这两个位置之间的障碍物数目是一样多的,符合要求,可以手算证明下),没有就标记这个状态是在这个位置出现的。因为数字较大,所以要选择一个比较好的hash方法,试了好几个都是wa,看网上的就行了,,,只能说这种hash方式的选择看经验了。
这样我们可以枚举泳道的右位置,计算出每个泳道中从0到这个位置的障碍物数目,求出最大与最小值。如果相等说明这个位置是目前长的泳道右端点。然后,因为要想等,如果要以这个位置为泳道的右端点,那么我们需要求一个想等的左端点。cnt[i] = A[i][j] - mi;这样的话,障碍物的数目就是mi个,求一个最远的左端点就好了,,,这样就需要hash一下,因为直接找的话时间消耗太大了,这里减了之后就会又一个差值状态,只需要求出这个状态出现的最早的位置就好了,出现过就是端点距离差+1(这里是因为出现了相同的差值状态,说明这两个位置之间的障碍物数目是一样多的,符合要求,可以手算证明下),没有就标记这个状态是在这个位置出现的。因为数字较大,所以要选择一个比较好的hash方法,试了好几个都是wa,看网上的就行了,,,只能说这种hash方式的选择看经验了。
// #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; // #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__ ) #else #define debug(...) #endif #define CLR(x) memset(x, 0,sizeof x) #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;} template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;} typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const ULL MOD = (1ULL << 63) - 1; const int maxn = 5e4 + 10; map<ULL, int> mp; int A[maxn][30]; int cnt[30]; void solve(int icase){ int L, K; scanf("%d%d",&L,&K); mp.clear(); memset(A, 0,sizeof A); for (int i = 0;i < K;++i){ int num, p; scanf("%d",&num); while(num--){ scanf("%d",&p); A[p][i]++; } } int ret=0,p=0; for (int i = 0;i < L;++i){ int mi = L + 1,ma = -1; for (int j = 0;j < K;++j){ if (i) A[i][j] += A[i-1][j]; mi = min(mi, A[i][j]); ma = max(ma, A[i][j]); } if (mi==ma) ret=i+1; for (int j = 0;j < K;++j){ cnt[j] = A[i][j]-mi; } // printf("(%d,",ret); LL tmp = 0; for (int j = K - 1;j >= 0;--j){ tmp ^= cnt[j]; tmp *= 12345678; // tmp ^= cnt[j]; // cout << "tmp " << tmp << " "; // tmp ^= (1ULL*cnt[j])%MOD; } int t = mp[tmp]; if (t){ ret = Get_Max(ret,i-t+1); }else{ mp[tmp]=i+1; } // printf("%d)\n",ret); // cout << "tmp = " << tmp << endl; } printf("Case %d: %d meter(s)\n",icase,ret); } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int t, icase = 0; scanf("%d",&t); while(t--){ solve(++icase); } return 0; }
相关文章推荐
- C语言基础总结
- Centos Java 从1.7升级为1.8
- Scala第一类函数
- Dynamic Language Runtime (DLR) 初深
- CocoaPods安装教程
- 蓝桥杯——数字三角形
- Bat的pushd和popd
- 算法库:Matlab与C++混合编程
- Android学习笔记:利用Tablelayout和viewpager实现防qq底部栏切换
- 三十二节 循环思维启蒙
- Yii2 模型实例化
- mysql 性能优化简述
- 数据结构-栈的相关理解和C语言基础实现
- 在asyncTask里执行asyncHttp操作报错的原因
- MySQL分区总结
- 【iOS】the executable was signed with invalid entitlements
- [转] openwrt关闭调试串口
- Android :JNI基本原理
- C语言指针类型
- nodejs中EventEmitter