UPC6604: Sandglass(思维)

6604: Sandglass

时间限制: 1 Sec  内存限制: 128 MB
提交: 312  解决: 66
[提交] [状态] [讨论版] [命题人: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<r2<..<rK≤109
1≤Q≤105
0≤t1<t2<..<tQ≤109
0≤ai≤X(1≤i≤Q)
All input values are integers.

样例输入

180
3
60 120 180
3
30 90
61 1
180 180

样例输出

60
1
120

复杂度O(n+q)

题意:有一个沙漏 一开始A部分在上面B部分在下面,现在要然后给一个序列每个数表示在此时刻将沙漏倒过来,q次查询每次输入t时刻并且初始值x表示A在0时刻拥有多少克沙子,总共为X;

思路:此题很锻炼思维能力,如果每次查找中规中矩的方法那么复杂度为O(n*q)1e10必定超时,那么就要考虑每次先不考虑输入的x,计算当前时刻的最近倒过来的那个时刻总共需要减去或者加上多少沙子,加上这个值,然后计算多余出来的部分,这里需要注意的事用minn = 0,maxn = X;这两个值来维护每次操作后沙子应该在那个范围之内,如果超过这个范围那么需要取一个边界值,即如果沙子为0了不可能是负的会一直是0,如果是X了也不会在漏沙子一直是X,除非出现倒转情况。

开始交一直Tle,用了读入挂还是Tle,然后结果是cout,告诉自己如果多次查询的题目一定用printf、scanf!!!!

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define FIN freopen("D://code//in.txt", "r", stdin)
#define ppr(i,x,n) for(int i = x;i <= n;i++)
#define rpp(i,n,x) for(int i = n;i >= x;i--)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxnn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
 
inline int read() {//读入挂
    int ret = 0, c, f = 1;
    for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
    if(c == '-') f = -1, c = getchar();
    for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
    if(f < 0) ret = -ret;
    return ret;
}
int r[maxnn];
struct node
{
	ll t,x;
}p[maxnn];
ll maxn,minn,val,h;
int n,X,q,k,flag;
int main()
{
	IO;
	X = read();
	n = read(); 
	ppr(i,1,n){r[i] = read();}
	q = read(); 
	ppr(i,1,q){p[i].t = read();p[i].x = read();}
	maxn = X;minn = 0;h = 0;k = 1;flag = -1;
	ppr(i,1,q)
	{
		while(k<=n && r[k]<=p[i].t)
		{
			val = (r[k] - r[k-1])*flag;
			h += val;flag *= -1;
			maxn += val;minn += val;
			if(maxn > X) maxn = X;if(maxn < 0) maxn = 0; 
			if(minn < 0) minn = 0;if(minn > X) minn = X;
			k++;
		}
		ll sum = p[i].x + h;ll add = (p[i].t - r[k-1])*flag;
		//cout<<minn<<" "<<maxn<<endl;
		if(sum < minn) sum = minn;if(sum > maxn) sum = maxn;
		sum += add;
		if(sum > X) sum = X;if(sum < 0) sum = 0;
		printf("%lld\n",sum);
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/Pandapan1997/article/details/81280109