csuoj1974: 神奇藥水

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) ,XX 和 YY 分別代表勤奮和聰明兩種原料在藥水中的濃度,其中 XX+ YY= 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 

s.t.k1k1+k2(X1,Y1)+k2k1+k2(X2,Y2)=(X,Y)s.t.k1k1+k2∗(X1,Y1)+k2k1+k2∗(X2,Y2)=(X,Y)

​容易知道最多有10001種藥水。將(X, Y) 視爲平面上的向量,能否配置當且僅當(X, Y) 集合中存在或夾在向量(X1, Y1)(X2, Y2) 之間。由於存在約束條件 XX + 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
**********************************************************************/



發佈了79 篇原創文章 · 獲贊 1 · 訪問量 8913
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章