[AtCoder][ARC082]Sandglass 题解

Sandglass

时间限制: 1 Sec 内存限制: 128 MB 
原题链接 https://arc082.contest.atcoder.jp/tasks/arc082_d

题目描述

We have a sandglass consisting of two bulbs, bulb A and bulb B. These bulbs contain some amount of sand. When we put the sandglass, either bulb A or B lies on top of the other and becomes the upper bulb. The other bulb becomes the lower bulb. 
The sand drops from the upper bulb to the lower bulb at a rate of 1 gram per second. When the upper bulb no longer contains any sand, nothing happens. 
Initially at time 0, bulb A is the upper bulb and contains a grams of sand; bulb B contains X−a grams of sand (for a total of X grams). 
We will turn over the sandglass at time r1,r2,..,rK. Assume that this is an instantaneous action and takes no time. Here, time t refer to the time t seconds after time 0. 
You are given Q queries. Each query is in the form of (ti,ai). For each query, assume that a=ai and find the amount of sand that would be contained in bulb A at time ti.

Constraints 
1≤X≤109 
1≤K≤105 
1≤r1

样例输入

180 

60 120 180 

30 90 
61 1 
180 180

样例输出

60 

120

题解

我的做法是进行带优化的模拟,因为题目输入是确保后一个时间一定大于前一个时间的,所以对于翻转的模拟总共只需要按顺序进行一次便可,最后使用数学结论根据时间和初始质量推出答案。 
需要特别注意的是,这道题会卡输入输出,如果不使用scanf/printf的话,必须要关闭同步锁且不能使用endl,不然会TLE。(可能是华东OJ的原因)

心疼那将近一半被输入输出卡掉的提交QAQ

代码

42 ms/1664 KB(AtCoder) 
80 ms/2080 KB(华东 OJ)

#include <iostream>
#include <algorithm>

using namespace std;
int x, k, q, t, a, low, up, add, delta, now, ans, r[100007];
bool flag;

int cal(int tt, int lower = 0, int upper = x) {
    if (tt < lower) return lower;
    if (tt > upper) return upper;
    return tt;
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

    cin >> x >> k;
    for (int i = 1; i <= k; i++) cin >> r[i];
    cin >> q;

    low = x, now = 1;
    while (q--) {
        cin >> t >> a;
        while (t >= r[now] && now <= k) {
            delta = (flag ? 1 : -1) * (r[now] - r[now - 1]), add += delta;
            up = cal(delta + up), low = cal(delta + low);
            flag = !flag, now++;
        }
        ans = cal((flag ? 1 : -1) * (t - r[now - 1]) + cal(a + add, up, low));
        cout << ans << '\n';
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/xfl03/p/9385769.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值