题解 SP58 【PICAD - Crime at Piccadily Circus】
题意分析
总共有 \(10\) 组数据,你应该在最外圈套个 \(10\) 次的循环!!!!!
在每组数据中,有案件可能的时间段,所有区间都是左闭右闭的,还有犯罪嫌疑人可能在的时间区间。
要统计同一时间(这个时间必须在案件发生时间段内)在的人数的最大值与最小值,这里将其离散化后用差分解决。
代码实现
set<int>S;
map<int,int>mp;
set<int>::iterator it;
因为懒,所以用 \(set\) 和 \(map\) 来离散。这两个数据结构不用说了吧。
S.insert(L); S.insert(R);
for(int i=1;i<=N;i++) fin>>A[i].l>>A[i].r, S.insert(A[i].l), S.insert(A[i].r);
for(it=S.begin();it!=S.end();it++) mp[*it]=++cnt;
这就是离散的具体过程了。
在处理差分之前,先来看看这么一组数据
1 2
2
1 1
2 2
这组数据的正确结果应该是 \(0\) \(1\),因为当时间为 \(1.5\) 时是没有任何一个人在现场的,时间戳可以是浮点数
L=mp[L]; R=mp[R]; memset(X,0,sizeof X); memset(I,0,sizeof I); cnt++;
for(int i=1;i<=N;i++) X[mp[A[i].l]]++, X[mp[A[i].r]+1]--, I[mp[A[i].l]]++, I[mp[A[i].r]]--;
for(int i=1;i<=cnt;i++){
X[i]+=X[i-1]; I[i]+=I[i-1]; if(i>R) break;
if(L<=i){
maxx=max(maxx,X[i]);
if(i!=R) minn=min(minn,I[i]);
}
}
这一块代码是差分,开了两个数组,\(X\) 数组用来刷最大值,\(I\) 数组用来刷最小值,这里注意一下啊,当 \(i=N\) 的时候是不能刷最小值的,因为会扩展到错误的值,因为在 \(K\) 个元素的区间内,实际可用 \(min\) 值只有 \(K-1\) 个。
到这里,这道题就解完了,完整代码不贴了,相信看到这里就能够解掉这道题。
Made By \(\operatorname{wheneveright}\).

浙公网安备 33010602011771号