时间限制: 1 Sec 内存限制: 128 MB
提交: 244 解决: 44
[提交] [状态] [讨论版] [命题人:admin]
题目描述
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
0≤t1
All input values are integers.
样例输入
180
3
60 120 180
3
30 90
61 1
180 180
样例输出
60
1
120
给你一个沙漏,告诉你沙漏里有多少沙子(同时这也是沙漏的上部分或下部分的容积),然后告诉你会进行k次翻转的时刻点(递增)
q次询问,问在初始值为ai的时候第t秒a部分(最开始是上半部分)里沙子的质量(t递增)
一开始觉得很简单,觉得可以模拟但可能超时,然后就写了下面这个代码,果然超时
#include
using namespace std;
int tim[100005];
int ans[100005];
int main()
{
int x;
int k;
scanf("%d%d",&x,&k);
for(int i=0;ix)
ai=x;
if(ai<0)
ai=0;
flag*=-1;
//printf("--%d\n",ai);
}
ai = ai+flag*(t-tim[j-1]);
if(ai>x)
ai=x;
if(ai<0)
ai=0;
printf("%d\n",ai);
}
return 0;
}
但是实际上应该这样想,可以模拟t秒时a部分所有的ai初始值的情况(也就是0---x),这样每次询问的时候再考虑这次输入的ai就可以了(因为询问的时间依次递增)
那么实际上可以得到一条曲线设x轴为ai的初始值,y轴为t秒后的a部分里的沙子质量,那么,
一开始,曲线就是个正比例函数(并且斜率是1),每过一秒,曲线向下(上 )平移一个单位,注意
移动后不能小于零,不能大于x,这样最多变成一个三段的分段函数,那么维护两个分界点即可
add是如果什么都不考虑,原图像的平移量,那么加上ai再mix(我写的一个函数,用来限制范围)一下就得到了当前的值,
因为t不一定是恰好在翻转点,那么要加上flag*(t-tim[j-1]),再限制在0----x之间就是答案了
#include
using namespace std;
int tim[100005];
int x,k,q;
int mix(int t,int l = 0,int r = x) {
return t>r?r :(t