题目传送门

题意:一个长度L的管子,起点在0。n次操作,0 p表示在p的位置放上蛋糕,1表示去吃掉最近的蛋糕(如果左右都有蛋糕且距离相同,那么吃同方向的蛋糕),问最终走了多少路程

分析:用multiset来保存蛋糕的位置,以当前的位置进行二分查找相邻的蛋糕的位置,模拟这个过程。当然也可以用线段树单点更新维护。

收获:当结果和暴力程序跑出来的一样却WA时,想想是否遗漏了某些情况的讨论

multiset:

/************************************************
* Author :Running_Time
* Created Time :2015-8-22 9:31:50
* File Name :C.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7; int main(void) {
int T, cas = 0; scanf ("%d", &T);
while (T--) {
multiset<int> S; S.clear ();
multiset<int>::iterator it, l, r;
int n, m; scanf ("%d%d", &n, &m);
ll ans = 0; int now = 0, d = 1;      //d == 0:左 d == 1: 右
while (m--) {
int op, p; scanf ("%d", &op);
if (op == 0) {
scanf ("%d", &p); S.insert (p);
}
else {
if (S.empty ()) continue;        //没蛋糕了
it = S.lower_bound (now); r = it, l = it;
if (it == S.end ()) {          //右边没蛋糕
l--;
ans += (now - *l);
if (*l < now) d = 0;     //当蛋糕在左边时才改变方向,下面类似
now = *l;
S.erase (l);
}
else if (it == S.begin ()) {      //左边没蛋糕
ans += (*r - now);
if (now < *r) d = 1;
now = *r;
S.erase (r);
}
else {                  //左右都有蛋糕
l--;
int dt0 = now - *l, dt1 = *r - now;
if (dt0 == dt1) {            //左右距离相等
if (d == 0) {
ans += dt0; now = *l;
S.erase (l);
}
else {
ans += dt1; now = *r;
S.erase (r);
}
}
else if (dt0 < dt1) {        //吃左边的蛋糕
ans += dt0; now = *l;
if (dt0) d = 0;
S.erase (l);
}
else {                //吃右边的蛋糕
ans += dt1; now = *r;
if (dt1) d = 1;
S.erase (r);
}
}
}
} printf ("Case %d: %I64d\n", ++cas, ans);
} return 0;
}

Segment_Tree:

#include <bits/stdc++.h>
using namespace std; #define lson l, mid, o << 1
#define rson mid + 1, r, o << 1 | 1
typedef long long ll;
const int N = 1e5 + 5;
const int INF = 0x3f3f3f3f;
struct Segment_Tree {
struct Node {
int mx, mn, cnt;
}node[N<<2];
void push_up(int o) {
node[o].mx = max (node[o<<1].mx, node[o<<1|1].mx);
node[o].mn = min (node[o<<1].mn, node[o<<1|1].mn);
}
void build(int l, int r, int o) {
if (l == r) {
node[o].mx = -INF; node[o].mn = INF;
node[o].cnt = 0; return ;
}
int mid = l + r >> 1;
build (lson); build (rson);
push_up (o);
}
void updata(int p, int c, int l, int r, int o) {
if (l == r && p == l) {
node[o].mx = node[o].mn = p;
node[o].cnt += c;
if (!node[o].cnt) {
node[o].mx = -INF; node[o].mn = INF;
}
return ;
}
int mid = l + r >> 1;
if (p <= mid) updata (p, c, lson);
else updata (p, c, rson);
push_up (o);
}
int query_left(int ql, int qr, int l, int r, int o) {
if (ql <= l && r <= qr) {
return node[o].mx;
}
int mid = l + r >> 1, ret = -INF;
if (ql <= mid) ret = max (ret, query_left (ql, qr, lson));
if (qr > mid) ret = max (ret, query_left (ql, qr, rson));
return ret;
}
int query_right(int ql, int qr, int l, int r, int o) {
if (ql <= l && r <= qr) {
return node[o].mn;
}
int mid = l + r >> 1, ret = INF;
if (ql <= mid) ret = min (ret, query_right (ql, qr, lson));
if (qr > mid) ret = min (ret, query_right (ql, qr, rson));
return ret;
}
}st; int main(void) {
int T, cas = 0; scanf ("%d", &T);
while (T--) {
int n, m; scanf ("%d%d", &n, &m);
n++;
st.build (1, n, 1);
ll ans = 0; int now = 1, d = 1;
while (m--) {
int op, p; scanf ("%d", &op);
if (op == 0) {
scanf ("%d", &p); p++;
st.updata (p, 1, 1, n, 1);
}
else {
int p1 = st.query_left (0, now, 1, n, 1);
int p2 = st.query_right (now, n, 1, n, 1);
if (p1 == -INF && p2 == INF) continue;
if (p2 == INF) {
ans += now - p1;
if (p1 < now) d = 0;
now = p1;
st.updata (p1, -1, 1, n, 1);
}
else if (p1 == -INF) {
ans += p2 - now;
if (p2 > now) d = 1;
now = p2;
st.updata (p2, -1, 1, n, 1);
}
else {
int dt0 = now - p1, dt1 = p2 - now;
if (dt0 == dt1) {
if (d == 0) {
ans += dt0; now = p1;
st.updata (p1, -1, 1, n, 1);
}
else {
ans += dt1; now = p2;
st.updata (p2, -1, 1, n, 1);
}
}
else if (dt0 < dt1) {
ans += dt0; now = p1;
if (dt0) d = 0;
st.updata (p1, -1, 1, n, 1);
}
else {
ans += dt1; now = p2;
if (dt1) d = 1;
st.updata (p2, -1, 1, n, 1);
}
}
}
}
printf ("Case %d: %I64d\n", ++cas, ans);
} return 0;
}

  

multiset || 线段树 HDOJ 4302 Holedox Eating的更多相关文章

  1. HDU 4302 Holedox Eating (线段树模拟)

    题意:一个老鼠在一条长度为L的直线上跑,吃蛋糕,老鼠只能沿直线移动.开始时没有蛋糕,老鼠的初始位置是0. 有两个操作,0 x 代表在位置x添加一个蛋糕: 1 代表老鼠想吃蛋糕.老鼠每次都会选择离自己最 ...

  2. hdu 4302 Holedox Eating(优先队列/线段树)

    题意:一只蚂蚁位与原点,在x轴正半轴上会不时地出现一些蛋糕,蚂蚁每次想吃蛋糕时选取最近的去吃,如果前后距离相同,则吃眼前的那一块(即方向为蚂蚁的正前),求最后蚂蚁行进距离. 思路:优先队列q存储蚂蚁前 ...

  3. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  4. EC R 87 div2 D. Multiset 线段树 树状数组 二分

    LINK:Multiset 主要点一下 二分和树状数组找第k大的做法. 线段树的做法是平凡的 开一个数组实现就能卡过. 考虑如树状数组何找第k大 二分+查询来判定是不优秀的. 考虑树状数组上倍增来做. ...

  5. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

  6. HDU 4302 Holedox Eating (STL + 模拟)

    Holedox Eating Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  7. 树状数组+二分||线段树 HDOJ 5493 Queue

    题目传送门 题意:已知每个人的独一无二的身高以及排在他前面或者后面比他高的人数,问身高字典序最小的排法 分析:首先对身高从矮到高排序,那么可以知道每个人有多少人的身高比他高,那么取较小值(k[i], ...

  8. HDU 4302 Holedox Eating(multiset)

    http://acm.hdu.edu.cn/showproblem.php?pid=4302 题意: 在一条直线上,会有多条命令,如果是0,那么就会在x位置处出现一个蛋糕,如果是1,某人就会找到最近的 ...

  9. 树链剖分+线段树 HDOJ 5029 Relief grain(分配粮食)

    题目链接 题意: 分粮食我就当成涂色了.有n个点的一棵树,在a到b的路上都涂上c颜色,颜色可重复叠加,问最后每一个点的最大颜色数量的颜色类型. 思路: 首先这题的输出是每一个点最后的情况,考虑离线做法 ...

随机推荐

  1. IntelliJ IDEA14.0.3+Maven+SpringMVC+Spring+Hibernate光速构建Java权限管理系统(三)

    注册登录 --利用简单的编写注册登录系统来打通从前端到后台的数据传输路径. 一.建立数据库.基本表 基本环境:mysql5,7.Navicat for MySQL11.0.9企业版. 我们在本地MyS ...

  2. 一个bug在redmine中的诞生到终结

    1.測试员測试出bug,跟踪状态为支持,状态为新建,指派给产品经理. 2.产品经理鉴定确觉得bug.改动跟踪状态为bug.指派给技术经理: 3.技术经理收到bug,指派给开发者: 4.开发者收到bug ...

  3. webstorm 6.0 注册码

    User Name: EMBRACE   License Key: ===== LICENSE BEGIN ===== 24718-12042010 00001h6wzKLpfo3gmjJ8xoTPw ...

  4. Python函数参数传递

    Python中函数参数的传递是采用传值方式,但是和C/C++有所不同 C/C++方式 void fun(int a) { a = 10; } void main() { int c =3; fun(c ...

  5. mysql学习笔记之mysql数据库的安装

    1.执行mysql安装包选择自己定义安装(安装路径不要带中文,否则安装会出错! ) 2.一个mysql想要操作成功须要有三部分:server端,数据段,数据. 3.server软件文件夹: 4.数据文 ...

  6. 报错:Binary XML file line #7: Error inflating class android.support.v7.widget.RecyclerView

    近期学习RecyclerView,使用eclipse引用RecyclerView.编写完demo后编译没有问题,一执行就挂掉,错误例如以下: 07-22 23:05:34.553: D/Android ...

  7. 机器学习笔记之PCA-SIFT总结

    不多说,直接上干货! PCA-SIFT算法在描述子构建上作了创新,主要是 将统计学中的主成分分析(PCA)应用于对描述子向量的降维,以提高匹配效率 . PCA 的原理是:一般有效信号的方差大,噪声的方 ...

  8. windows下使用mingw和msys编译GOTOBLAS和OpenBLAS

    在windows下利用msys编译openBLAS若遇到错误提示: gcc: CreateProcess : No such file or directory 问题原因参考:http://www.c ...

  9. 【iOS系列】-A server with the specified hostname could not be found.问题解决

    [iOS系列]-A server with the specified hostname could not be found.问题解决 Reveal 在iOS开发中可以方便查看界面的布局,较为方便的 ...

  10. 【iOS系列】-iOS查看沙盒文件图文教程(真机+模拟器)

    [iOS系列]-iOS查看沙盒文件图文教程(真机+模拟器) 1:模拟器 1.1 方法1: 程序中打印一下的地址,能直接前往沙盒路径. NSString *path = [NSSearchPathFor ...