Description
對於csuxushu來說,能夠在CSU(California State University)組織2017年的ACM暑期集訓讓他感到十分榮幸。 csuxushu是一名充滿夢想的程序員,因此他也希望來參加暑期集訓的ACM萌新們和他一樣懷揣着書寫CSU-ACM歷史的夢想。 一個偶然的機會,他在機房的某個角落得到了一本來自遠古神犇的藥水配方祕籍。祕籍上記載了許多AC藥水配方,每一種藥水都需要用兩種原料 <勤奮,聰明> 按一定的比例配置而成。
“只要萌新喝下這些藥水,他們的實力將有質的提升!”
——《遠古AC藥水祕籍》
此刻萌新們正在機房內和題目奮戰,耳邊的WA聲不絕於耳。此情此景,csuxushu下定決心要爲萌新們配置這些藥水。 但是這兩種原料市面上並不出售,因此只能由一些已有藥水混合而成。爲此他四處搜尋,機房不時放進新的藥水和運出藥水,並且在機房內的每種藥水量都保證足夠多。作爲全CSU最聰明的程序員,對於每一個神奇藥水配方,你能告訴他能否配成嗎?
Input
多組數據。
對於每組數據,第一行一個整數N(1 < =N < =105),代表操作數。
接下來N行,每行一個三元組(K, X, Y) ,X 和 Y 分別代表勤奮和聰明兩種原料在藥水中的濃度,其中 X% + Y% = 100%
。
K = 0 :詢問是否可以配置神奇藥水(X, Y) ;
K = 1 :新增一種原料藥水(X, Y) ;
K = −1 :刪除所有原料藥水(X, Y) ,如果沒有這種藥水則忽略此操作;
Output
對於每個K = 0 的詢問輸出一行,Yes或No。
Sample Input
6 1 65.00 35.00 0 93.58 6.42 1 44.64 55.36 1 68.27 31.73 0 54.36 45.64 0 46.04 53.96
Sample Output
No Yes Yes
Hint
對於給出的詢問(X, Y) ,判斷集合中能否找到 (X1, Y1), (X2, Y2) ,並且∃k1, k2 ∈ R+ ∪ 0
容易知道最多有10001種藥水。將(X, Y) 視爲平面上的向量,能否配置當且僅當(X, Y) 集合中存在或夾在向量(X1, Y1), (X2, Y2) 之間。由於存在約束條件 X + Y = 100 ,實際上這些點在一條直線上,因此只要判斷橫座標的位置關係即可。
使用STL中的set維護插入和刪除操作O(logn),並且利用set的有序性找到橫座標的最大和最小值判斷即可O(1)。總的複雜度:O(nlogn)
注意判斷集合是否爲空以及橫座標的邊界情況。
代碼:#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<set>
using namespace std;
set<double> s;
int main()
{
int t;
while(scanf("%d",&t)!=EOF)
{
s.clear();
for(int i = 0;i<t;i++)
{
set<double>::iterator it ;
int k;
double a,b;
scanf("%d",&k);
scanf("%lf%lf",&a,&b);
if(k==1)
{
s.insert(a);
}
else if(k==-1)
{
s.erase(a);
}
else if(k==0)
{
if(s.empty())
{
printf("No\n");
continue;
}
it = s.begin();
double help1 = *it;
it = s.end();
it--;
double help2 = *it;
if(a>=help1&&a<=help2)
printf("Yes\n");
else printf("No\n");
}
}
}
}
/**********************************************************************
Problem: 1974
User: liyingshou
Language: C++
Result: AC
Time:168 ms
Memory:2156 kb
**********************************************************************/