您的位置:首页 > 其它

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方式的选择看经验了。

// #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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: