中石油 6604
题目来源:http://exam.upc.edu.cn/problem.php?id=6604
题目大意:给定两个容器A B,开始时A在上B在下,在给定的时间节点两者无损耗反转一次,每个容器里有一定量的沙子,沙子每秒会从上面的容器里流到下面的容器中 1 ,现给定沙子的总质量x,反转的次数和每次反转的时间节点,然后有q个询问,每次询问有两个值一个是时间,另一个是初始时A中的沙子的质量,求A中的沙子质量。
分析:在q个询问中每次询问的时间都是递增的(刚开始也看见,看了题解才知道……),然后可以根据这个“特点”每次都记录下来,并且每个时刻的上下界都需要记录(判断是否越界)
具体实现代码如下:
#include <cstdio>
int a[100010]={0};
int x,k;
int judge(int y)
{
if(y<0)
return 0;
else if(y>x)
return x;
else
return y;
}//判断是否在初始值内
int main()
{
scanf("%d %d",&x,&k);
for(int i=1;i<=k;i++)
scanf("%d",&a[i]);
a[0]=0;
int q;
scanf("%d",&q);
int j=1;
int sum=0,num=0;
int maxx=x,minn=0;
int flag=-1;
for(int i=0;i<q;i++)
{
int t,n;
scanf("%d %d",&t,&n);//时间递增
int ans=0;
while(t>=a[j]&&j<=k)
{
sum=flag*(a[j]-a[j-1]);
num+=sum;
minn+=sum;//下界
maxx+=sum;//上界
minn=judge(minn);
maxx=judge(maxx);
flag=-flag;
j++;
}
int ss=num+n;//加上每次的A中的初始值后判断是否在范围内(此时的上下界已更新为上个时间节点时的范围)
if(ss<minn)
ss=minn;
else if(ss>maxx)
ss=maxx;
else
ss+=0;
ans=judge(ss+flag*(t-a[j-1]));//累加的和(之前的各个时间节点的和)再加上此次未到下个节点的部分
printf("%d\n",ans);
}
}