模拟 - BZOJ 1510 [POI2006] Kra-The Disks
BZOJ 1510 [POI2006] Kra-The Disks
描述
Johnny 在生日时收到了一件特殊的礼物,这件礼物由一个奇形怪状的管子和一些盘子组成. 这个管子是由许多不同直径的圆筒(直径也可以相同) 同轴连接而成. 这个管子的底部是封闭的,顶部是打开的.
每个圆筒的高度都是相等的, 玩具中所带的盘子也是一些高度和它们相同的圆筒,直径有大有小.
Johnny 发明了一种游戏,把盘子从管子顶部一个接一个的扔下去,他想知道最后这些盘子落在了哪,假设盘子落下过程中圆心和管子的轴一直保持一致,盘子掉下去以后,要么被某个圆筒卡住,要么就是因为掉在了以前的一个盘子上而停住.
Johnny 想知道他最后扔下去的那个盘子掉在了哪个位置,你来帮他吧.
输入
第一行两个整数 n 和 m表示水管包含的圆筒数以及盘子总数.
第二行给出 n 个整数 r1, r2,...,rn表示水管从上到下所有圆筒的直径. 第三行给出 m 个整数 k1, k2,..., km分别表示 Johnny 依次扔下去的盘子直径.
输出
一个整数输出最后一个盘子掉在了哪一层,如果盘子不能扔进水管,那么打印 0.
样例
Sample Input
7 3
5 6 4 3 6 2 3
3 2 5
Sample Output
2
提示
1<= n, m<= 300 000;1 <=ri<= 1 000 000 000 for 1<= i<= n;1<= kj<= 1000 000 000 for 1<= j<= m
对于某一层来说,如果它比前面一层要宽的话,那么那一层多出来的宽度什么卵用都没有,会被上一层卡住。
所以可以扫一遍,找到每一层的有用的宽度。
接下来再扫一遍,找到每一个盘子会落在哪一层。
去他的二分!
O(n)复杂度就可以了!
代码蒯上
#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gotcha()
{
register int _a=0;bool _b=1;register char _c=getchar();
while(_c<'0' || _c>'9'){if(_c=='-')_b=0;_c=getchar();}
while(_c>='0' && _c<='9')_a=_a*10+_c-48,_c=getchar();
return _b?_a:-_a;
}
const int _ = 300002;
int r[_]={0},pl[_]={0},n,m;
int main()
{
register int i,mi=2e9,now;
n=gotcha(),m=gotcha();now=n+1;
for(i=1;i<=n;i++)r[i]=gotcha();
for(i=1;i<=m;i++)pl[i]=gotcha();
for(i=1;i<=n;i++)mi=min(mi,r[i]),r[i]=mi;
for(i=1;i<=m;i++)
{
for(now--;now>=1;--now)if(pl[i]<=r[now])break;
if(now<=0)break;
}
printf("%d",now);
return 0;
}