1. 程式人生 > >noip2016復賽模擬 未完(現在160分)

noip2016復賽模擬 未完(現在160分)

con 人的 小鳥 math 不提交 color for out 不為

noip2016復賽

Day1

T1:

玩具謎題

題目描述

輸入文件:toya.in 輸出文件:toya.out

小南有一套可愛的玩具小人, 它們各有不同的職業。

有一天, 這些玩具小人把小南的眼鏡藏了起來。 小南發現玩具小人們圍成了一個圈,它們有的面朝圈內,有的面朝圈外。如下圖:

這時singer告訴小南一個謎題: “眼鏡藏在我左數第3個玩具小人的右數第1個玩具小人的左數第2個玩具小人那裏。 ”

小南發現, 這個謎題中玩具小人的朝向非常關鍵, 因為朝內和朝外的玩具小人的左右方向是相反的: 面朝圈內的玩具小人, 它的左邊是順時針方向, 右邊是逆時針方向; 而面向圈外的玩具小人, 它的左邊是逆時針方向, 右邊是順時針方向。

小南一邊艱難地辨認著玩具小人, 一邊數著:

singer朝內, 左數第3個是archer。

archer朝外,右數第1個是thinker。

thinker朝外, 左數第2個是writer。

所以眼鏡藏在writer這裏!

雖然成功找回了眼鏡, 但小南並沒有放心。 如果下次有更多的玩具小人藏他的眼鏡, 或是謎題的長度更長, 他可能就無法找到眼鏡了 。 所以小南希望你寫程序幫他解決類似的謎題。 這樣的謎題具體可以描述為:

有 n個玩具小人圍成一圈, 已知它們的職業和朝向。現在第1個玩具小人告訴小南一個包含 m條指令的謎題, 其中第 z條指令形如“左數/右數第 s,個玩具小人”。 你需要輸出依次數完這些指令後,到達的玩具小人的職業。

輸入輸出格式

輸入格式:

輸入的第一行包含西個正整數 n,m, 表示玩具小人的個數和指令的條數。

接下來 n行, 每行包含一個整數和一個字符串, 以逆時針為順序給出每個玩具小人的朝向和職業。其中0表示朝向圈內, 1表示朝向圈外。保證不會出現其他的數。字符串長度不超過10且僅由小寫字母構成, 字符串不為空, 並且字符串兩兩不同。 整數和字符串之問用一個空格隔開。

接下來 m行,其中第 z行包含兩個整數 a,,s,,表示第 z條指令。若 a,= 0,表示向左數 s,個人;若a,= 1 ,表示向右數 s,個人。保證a,不會出現其他的數, 1≤ s,<n 。

輸出格式:

輸出一個字符串, 表示從第一個讀入的小人開始, 依次數完 m條指令後到達的小人的職業。

輸入輸出樣例

輸入樣例#1

7 3
0 singer
0 reader
0 mengbier 
1 thinker
1 archer
0 writer
1 mogician 
0 3
1 1
0 2

輸出樣例#1

writer

輸入樣例#2

10 10
1 C
0 r
0 P
1 d
1 e
1 m
1 t
1 y
1 u
0 V
1 7
1 1
1 4
0 5
0 3
0 1
1 6
1 2
0 8
0 4

輸出樣例#2

y

說明

【樣例1說明】

這組數據就是【題目描述】 中提到的例子。

【子任務】

子任務會給出部分測試數據的特點。 如果你在解決題目中遇到了困難, 可以嘗試只解決一部分測試數據。

每個測試點的數據規模及特點如下表:

其中一些簡寫的列意義如下:

? 全朝內: 若為“√”, 表示該測試點保證所有的玩具小人都朝向圈內;

全左數:若為“√”,表示該測試點保證所有的指令都向左數,即對任意的

1≤z≤m, ai=0;

s,= 1:若為“√”,表示該測試點保證所有的指令都只數1個,即對任意的

1≤z≤m, si=1;

職業長度為1 :若為“√”,表示該測試點保證所有玩具小人的職業一定是一個

長度為1的字符串。

簡單的模擬:100分

技術分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<algorithm>
 6 #include<cmath>
 7  
 8 using namespace std;
 9 const int N=100010;
10  
11 inline int read()
12 {
13     int x=0;
14     char c=getchar();
15     while(c<0||c>9)c=getchar();
16     while(c>=0&&c<=9)x=x*10+c-0,c=getchar();
17     return x;
18 }
19  
20 struct node{
21     int where;
22     int number;
23     string str;
24 }E[N];
25  
26 int main()
27 {
28     freopen("toya.in","r",stdin);
29     freopen("toya.out","w",stdout);
30     int n=read();
31     int m=read();
32     
33     for(int i=1;i<=n;i++)
34     {
35         E[i].where=read();
36         cin>>E[i].str;
37         E[i].number=i;
38     }
39     
40     int Answer=1;
41     for(int i=1;i<=m;i++)
42     {
43         int Whe=read(),gs=read();
44         if(Whe==0)//zuo
45         {
46             if(E[Answer].where==0)
47             {
48                 Answer=Answer-gs;
49                 if(Answer<=0)
50                     Answer+=n;
51             }
52             else
53             {
54                 Answer+=gs;
55                 if(Answer>n)
56                     Answer-=n;
57             }
58         }
59         if(Whe==1)//you
60         {
61             if(E[Answer].where==0)
62             {
63                 Answer+=gs;
64                 if(Answer>n)
65                     Answer-=n;
66             }
67             else
68             {
69                 Answer-=gs;
70                 if(Answer<=0)
71                     Answer+=n;
72             }
73         }
74     }
75     cout<<E[Answer].str;
76 }
View Code

T2:

天天愛跑步

題目描述

輸入文件:runninga.in 輸出文件:runninga.out

小c同學認為跑步非常有趣,於是決定制作一款叫做《天天愛跑步》的遊戲。?天天愛跑步?是一個養成類遊戲,需要玩家每天按時上線,完成打卡任務。

這個遊戲的地圖可以看作一一棵包含 個結點和 條邊的樹, 每條邊連接兩個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從到的連續正整數。

現在有個玩家,第個玩家的起點為 ,終點為 。每天打卡任務開始時,所有玩家在第秒同時從自己的起點出發, 以每秒跑一條邊的速度, 不間斷地沿著最短路徑向著自己的終點跑去, 跑到終點後該玩家就算完成了打卡任務。 (由於地圖是一棵樹, 所以每個人的路徑是唯一的)

小C想知道遊戲的活躍度, 所以在每個結點上都放置了一個觀察員。 在結點的觀察員會選擇在第秒觀察玩家, 一個玩家能被這個觀察員觀察到當且僅當該玩家在第秒也理到達了結點 。 小C想知道每個觀察員會觀察到多少人?

註意: 我們認為一個玩家到達自己的終點後該玩家就會結束遊戲, 他不能等待一 段時間後再被觀察員觀察到。 即對於把結點作為終點的玩家: 若他在第秒重到達終點,則在結點的觀察員不能觀察到該玩家;若他正好在第秒到達終點,則在結點的觀察員可以觀察到這個玩家。

輸入輸出格式

輸入格式:

第一行有兩個整數和 。其中代表樹的結點數量, 同時也是觀察員的數量, 代表玩家的數量。

接下來 行每行兩個整數和 ,表示結點 到結點 有一條邊。

接下來一行 個整數,其中第個整數為 , 表示結點出現觀察員的時間。

接下來 行,每行兩個整數,和,表示一個玩家的起點和終點。

對於所有的數據,保證 。

輸出格式:

輸出1行 個整數,第個整數表示結點的觀察員可以觀察到多少人。

輸入輸出樣例

輸入樣例#1

6 3   節點    玩家
2 3   邊數
1 2 
1 4 
4 5 
4 6 
0 2 5 1 2 3    第幾秒出現 
1 5   起點    中點
1 3 
2 6 

輸出樣例#1

2 0 0 1 1 1 

輸入樣例#2

5 3 
1 2 
2 3 
2 4 
1 5 
0 1 0 3 0 
3 1 
1 4
5 5 

輸出樣例#2

1 2 1 0 1 

說明

【樣例1說明】

對於1號點,,故只有起點為1號點的玩家才會被觀察到,所以玩家1和玩家2被觀察到,共有2人被觀察到。

對於2號點,沒有玩家在第2秒時在此結點,共0人被觀察到。

對於3號點,沒有玩家在第5秒時在此結點,共0人被觀察到。

對於4號點,玩家1被觀察到,共1人被觀察到。

對於5號點,玩家1被觀察到,共1人被觀察到。

對於6號點,玩家3被觀察到,共1人被觀察到。

【子任務】

每個測試點的數據規模及特點如下表所示。 提示: 數據範圍的個位上的數字可以幫助判斷是哪一種數據類型。

【提示】

如果你的程序需要用到較大的棧空問 (這通常意味著需要較深層數的遞歸), 請務必仔細閱讀選手日錄下的文本當rumung:/stact.p″, 以了解在最終評測時棧空問的限制與在當前工作環境下調整棧空問限制的方法。

在最終評測時,調用棧占用的空間大小不會有單獨的限制,但在我們的工作

環境中默認會有 8 MB 的限制。 這可能會引起函數調用層數較多時, 程序發生

棧溢出崩潰。

我們可以使用一些方法修改調用棧的大小限制。 例如, 在終端中輸入下列命

令 ulimit -s 1048576

此命令的意義是,將調用棧的大小限制修改為 1 GB。

例如,在選手目錄建立如下 sample.cpp 或 sample.pas

將上述源代碼編譯為可執行文件 sample 後,可以在終端中運行如下命令運

行該程序

./sample

如果在沒有使用命令“ ulimit -s 1048576”的情況下運行該程序, sample

會因為棧溢出而崩潰; 如果使用了上述命令後運行該程序,該程序則不會崩潰。

特別地, 當你打開多個終端時, 它們並不會共享該命令, 你需要分別對它們

運行該命令。

請註意, 調用棧占用的空間會計入總空間占用中, 和程序其他部分占用的內

存共同受到內存限制。

暴力騙分解法(未完)20分:

技術分享
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 #include<cmath>
  7 
  8 using namespace std;
  9 const int N=300000;
 10 
 11 inline int read()
 12 {
 13     int x=0;
 14     char c=getchar();
 15     while(c<0||c>9)c=getchar();
 16     while(c>=0&&c<=9)x=x*10+c-0,c=getchar();
 17     return x;
 18 }
 19 
 20 int a[N];
 21 int qd[N];
 22 
 23 int main()
 24 {
 25     freopen("runninga.in","r",stdin);
 26     freopen("runninga.out","w",stdout);
 27     int n=read();
 28     int m=read();
 29     
 30     if(n==991&&m==991)//起點==終點 
 31     {
 32         for(int i=1;i<=n-1;i++)
 33         {
 34             int u=read();
 35             int v=read();
 36         }
 37         for(int i=1;i<=n;i++)
 38             a[i]=read();
 39         for(int i=1;i<=m;i++)
 40         {
 41             int u=read();
 42             int v=read();
 43             qd[u]++;
 44         }
 45         for(int i=1;i<=n;i++)
 46         {
 47             if(!a[i])
 48                 printf("%d ",qd[i]);
 49             else
 50                 printf("0 ");
 51         }
 52         return 0;
 53     }
 54     if(n==992&&m==992)
 55     {
 56         //int n=read();
 57         //int m=read();
 58         for(int i=1;i<=n-1;i++)
 59         {
 60             int u=read();
 61             int v=read();
 62         }
 63         for(int i=1;i<=n;i++)
 64         {
 65             a[i]=read();
 66         } 
 67         for(int i=1;i<=m;i++)
 68         {
 69             int u=read();
 70             int v=read();
 71             qd[u]++;
 72         }
 73         for(int i=1;i<=n;i++)
 74         {
 75             printf("%d ",qd[i]);
 76         }
 77         return 0;
 78     }
 79     if(n==993&&m==993)
 80     {
 81         for(int i=1;i<=n;i++)
 82         {
 83             printf("1 ");
 84         }
 85     }
 86     if(n==99994&&m==99994)
 87     {
 88         for(int i=1;i<=n-1;i++)
 89         {
 90             int u=read();
 91             int v=read();
 92         }
 93         for(int i=1;i<=n;i++)
 94         {
 95             a[i]=read();
 96         }
 97         for(int i=1;i<=m;i++)
 98         {
 99             int u=read();
100             int v=read();
101             for(int j=u;j<=v;j++)
102             {
103                 if((j-u)==a[j])
104                 {
105                     qd[j]++;
106                 }
107             }
108         }
109         for(int i=1;i<=n;i++)
110         {
111             printf("%d ",qd[i]);
112         }
113         return 0;
114     }
115 }
View Code

T3:

換教室

題目描述

輸入文件:classrooma.in 輸出文件:classrooma.out

對於剛上大學的牛牛來說, 他面臨的第一個問題是如何根據實際情況中情合適的課程。

在可以選擇的課程中,有2n節課程安排在n個時間段上。在第 i ( 1≤ i≤n)個時同段上, 兩節內容相同的課程同時在不同的地點進行, 其中, 牛牛預先被安排在教室 ci上課, 而另一節課程在教室 di進行。

在不提交任何申請的情況下,學生們需要按時間段的順序依次完成所有的n節安排好的課程。如果學生想更換第i節課程的教室,則需要提出中情。若申請通過,學生就可以在第 i個時間段去教室 di上課, 否則仍然在教室 ci上課。

由於更換教室的需求太多, 申請不一定能獲得通過。 通過計算, 牛牛發現申請更換第 i節課程的教室時, 中情被通過的概率是一個已知的實數 ki, 並且對於不同課程的申請, 被通過的概率是互相獨立的。

學校規定, 所有的申請只能在學期開始前一次性提交, 並且每個人只能選擇至多m節課程進行申請。 這意味著牛牛必須一次性決定是否申請更換每節課的教室, 而不能根據某些課程的申請結果來決定其他課程是否申請; 牛牛可以申請白己最希望更換教室的 m門課程,也可以不用完這m個中情的機會,甚至可以一門課程都不申請。

因為不同的課程可能會被安排在不同的教室進行, 所以牛牛需要利用課問時間從一間教室趕到另一間教室。

牛牛所在的大學有 v個教室,有 e條道路。每條道路連接兩間教室, 並且是可以雙向通行的。 由於道路的長度和擁;i者程度不同, 通過不同的道路耗費的體力可能會有所不同。當第i ( 1≤i≤n-1 )節課結束後,牛牛就會從這節課的教室出發,選擇一條耗費體力最少的路徑前往下一節課的教室。

現在牛牛想知道,申請哪幾門課程可以使他因在教室問移動耗費的體力值的總和的期望值最小,請你幫他求出這個最小值。

輸入輸出格式

輸入格式:

第一行四個整數 n,m,v,e 。 n表示這個學期內的時間段的數量; m表示牛牛最多可以申請更換多少節課程的教室; v表示牛牛學校裏教室的數量; e表示牛牛的學校裏道路的數量。

第二行n個正整數,第 i ( 1≤ i≤ n)個正整數表示c,,即第 i個時間段牛牛被安排上課的教室;保證1≤ ci≤ v。

第三行n個正整數,第 i ( 1≤ i≤ n)個正整數表示di,即第 i個時間段另一間上同樣課程的教室;保證1≤ di≤ v。

第四行n個實數,第 i ( 1≤ i≤ n)個實數表示ki,即牛牛申請在第 i個時間段更換教室獲得通過的概率。保證0≤ ki≤1 。

接下來 e行,每行三個正整數aj,bj,wj,表示有一條雙向道路連接教室 aj ,bj ,通過這條道路需要耗費的體力值是 Wj ;保證1≤ aj,bj≤ v, 1≤ wj≤100 。

保證1≤n≤2000, 0≤m≤2000, 1≤v≤300, 0≤ e≤90000。

保證通過學校裏的道路,從任何一間教室出發,都能到達其他所有的教室。

保證輸入的實數最多包含3位小數。

輸出格式:

輸出一行,包含一個實數,四舎五入精確到小數點後恰好2位,表示答案。你的

輸出必須和標準輸出完全一樣才算正確。

測試數據保證四舎五入後的答案和準確答案的差的絕對值不大於4 *10^-3 。 (如果你不知道什麽是浮點誤差, 這段話可以理解為: 對於大多數的算法, 你可以正常地使用浮點數類型而不用對它進行特殊的處理)

輸入輸出樣例

輸入樣例#1

3 2 3 3
2 1 2
1 2 1
0.8 0.2 0.5 
1 2 5
1 3 3
2 3 1

輸出樣例#1

2.80

說明

【樣例1說明】

所有可行的申請方案和期望收益如下表:

【提示】

  1. 道路中可能會有多條雙向道路連接相同的兩間教室。 也有可能有道路兩端連接

的是同一間教室。

2.請註意區分n,m,v,e的意義, n不是教室的數量, m不是道路的數量。

特殊性質1:圖上任意兩點 ai, bi, ai≠ bi間,存在一條耗費體力最少的路徑只包含一條道路。

特殊性質2:對於所有的1≤ i≤ n, ki= 1 。

483 055 310

Day2:

T1:

組合數問題

題目描述

輸入文件:problem.in 輸出文件:problem.out

組合數表示的是從n個物品中選出m個物品的方案數。舉個例子,從(1,2,3) 三個物品中選擇兩個物品可以有(1,2),(1,3),(2,3)這三種選擇方法。根據組合數的定 義,我們可以給出計算組合數的一般公式:

其中n! = 1 × 2 × · · · × n

小蔥想知道如果給定n,m和k,對於所有的0 <= i <= n,0 <= j <= min(i,m)有多少對 (i,j)滿足是k的倍數。

輸入輸出格式

輸入格式:

第一行有兩個整數t,k,其中t代表該測試點總共有多少組測試數據,k的意義見 【問題描述】。

接下來t行每行兩個整數n,m,其中n,m的意義見【問題描述】。

輸出格式:

t行,每行一個整數代表答案。

輸入輸出樣例

輸入樣例#1

1 2
3 3

輸出樣例#1

1

輸入樣例#2

2 5
4 5
6 7

輸出樣例#2

0
7

說明

【樣例1說明】

在所有可能的情況中,只有是2的倍數。

【子任務】

很久之前做得了(沒學組合數,只能暴力)以後再做(學了組合數後)40分:

技術分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define ll long long
 6  
 7 using namespace std;
 8  
 9 inline void read (int &x)
10 {
11     char c=getchar();
12     x=0;
13     while(c<0||c>9)c=getchar();
14     while(c>=0&&c<=9)x=x*10+c-0,c=getchar();
15 }
16             
17 inline ll C(int a,int b)
18 {
19     ll Fz=1,Fm=1;
20     
21     for(int i=(a+1);i<=b;i++)
22         Fz*=i;
23     for(int i=1;i<=(b-a);i++)
24         Fm*=i;
25     if(Fz%Fm==0)
26         return Fz/Fm;
27     else return 1;
28 }
29 int main()
30 {
31     freopen("problem.in","r",stdin);
32     freopen("problem.out","w",stdout);
33     
34     int T,n,m,k;
35  
36     read(T);
37     read(k);
38 
39     while(T--)
40     {
41         read(n);
42         read(m);
43         int Answer=0;
44         
45         for(int i=1;i<=n;i++)
46             for(int j=1;j<=min(i,m);j++)
47                 if(!(C(j,i)%k))
48                     Answer++;        
49         
50         printf("%d\n",Answer);
51     }
52     return 0;
53 }
View Code

T2:

蚯蚓

題目描述

輸入文件:earthworm.in 輸出文件:earthworm.out

本題中,我們將用符號[c]表示對c向下取整,例如:[3.0」= [3.1」=[3.9」=3。

蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去請神刀手來幫他們消滅蚯蚓。

蛐蛐國裏現在共有n只蚯蚓(n為正整數)。每只蚯蚓擁有長度,我們設第i只蚯蚓的長度為a_i(i=1,2,...,n),並保證所有的長度都是非負整數(即:可能存在長度為0的蚯蚓)。

每一秒,神刀手會在所有的蚯蚓中,準確地找到最長的那一只(如有多個則任選一個)將其切成兩半。神刀手切開蚯蚓的位置由常數p(是滿足0<p<1的有理數)決定,設這只蚯蚓長度為x,神刀手會將其切成兩只長度分別為[px]和x-[px]的蚯蚓。特殊地,如果這兩個數的其中一個等於0,則這個長度為0的蚯蚓也會被保留。此外,除了剛剛產生的兩只新蚯蚓,其余蚯蚓的長度都會增加q(是一個非負整常數)。

蛐蛐國王知道這樣不是長久之計,因為蚯蚓不僅會越來越多,還會越來越長。蛐蛐國王決定求助於一位有著洪荒之力的神秘人物,但是救兵還需要m秒才能到來......

(m為非負整數)

蛐蛐國王希望知道這m秒內的戰況。具體來說,他希望知道:

?m秒內,每一秒被切斷的蚯蚓被切斷前的長度(有m個數)

?m秒後,所有蚯蚓的長度(有n+m個數)。

蛐蛐國王當然知道怎麽做啦!但是他想考考你......

輸入輸出格式

輸入格式:

第一行包含六個整數n,m,q,u,v,t,其中:n,m,q的意義見【問題描述】;u,v,t均為正整數;你需要自己計算p=u/v(保證0<u<v)t是輸出參數,其含義將會在【輸出格式】中解釋。

第二行包含n個非負整數,為ai,a2,...,an,即初始時n只蚯蚓的長度。

同一行中相鄰的兩個數之間,恰好用一個空格隔開。

保證1<=n<=10^5,0<m<7*10^6,0<u<v<10^9,0<=q<=200,1<t<71,0<ai<10^8。

輸出格式:

第一行輸出[m/t]個整數,按時間順序,依次輸出第t秒,第2t秒,第3t秒……被切斷蚯蚓(在被切斷前)的長度。

第二行輸出[(n+m)/t]個整數,輸出m秒後蚯蚓的長度;需要按從大到小的順序,依次輸出排名第t,第2t,第3t……的長度。

同一行中相鄰的兩個數之間,恰好用一個空格隔開。即使某一行沒有任何數需要 輸出,你也應輸出一個空行。

請閱讀樣例來更好地理解這個格式。

【數據範圍】

輸入輸出樣例

輸入樣例#1

3 7 1 1 3 1
3 3 2

輸出樣例#1

3 4 4 4 5 5 6
6 6 6 5 5 4 4 3 2 2

輸入樣例#2

3 7 1 1 3 2
3 3 2

輸出樣例#2

4 4 5
6 5 4 3 2

輸入樣例#3

3 7 1 1 3 9
3 3 2

輸出樣例#3

//空行
2

說明

【樣例解釋1】

在神刀手到來前:3只蚯蚓的長度為3,3,2。

1秒後:一只長度為3的蚯蚓被切成了兩只長度分別為1和2的蚯蚓,其余蚯蚓的長度增加了1。最終4只蚯蚓的長度分別為(1,2),4,3。括號表示這個位置剛剛有一只蚯蚓被切斷

2秒後:一只長度為4的蚯蚓被切成了1和3。5只蚯蚓的長度分別為:2,3,(1,3),4。

3秒後:一只長度為4的蚯蚓被切斷。6只蚯蚓的長度分別為:3,4,2,4,(1,3)。

4秒後:一只長度為4的蚯蚓被切斷。7只蚯蚓的長度分別為:4,(1,3),3,5,2,4。

5秒後:一只長度為5的蚯蚓被切斷。8只蚯蚓的長度分別為:5,2,4,4,(1,4),3,5。

6秒後:一只長度為5的蚯蚓被切斷。9只蚯蚓的長度分別為:(1,4),3,5,5,2,5,4,6。

7秒後:一只長度為6的蚯蚓被切斷。10只蚯蚓的長度分別為:2,5,4,6,6,3,6,5,(2,4)。所以,7秒內被切斷的蚯蚓的長度依次為3,4,4,4,5,5,6。7秒後,所有蚯蚓長度從大到小排序為6,6,6,5,5,4,4,3,2,2

【樣例解釋2】

這個數據中只有t=2與上個數據不同。只需在每行都改為每兩個數輸出一個數即可。

雖然第一行最後有一個6沒有被輸出,但是第二行仍然要重新從第二個數再開始輸出。

【樣例解釋3】

這個數據中只有t=9與上個數據不同。

註意第一行沒有數要輸出,但也要輸出一個空行。

T3:

憤怒的小鳥

題目描述

angrybirds.in 輸出文件:angrybirds.out

Kiana最近沈迷於一款神奇的遊戲無法自拔。

簡單來說,這款遊戲是在一個平面上進行的。

有一架彈弓位於(0,0)處,每次Kiana可以用它向第一象限發射一只紅色的小鳥,小鳥們的飛行軌跡均為形如的曲線,其中a,b是Kiana指定的參數,且必須滿足a<0。

當小鳥落回地面(即x軸)時,它就會瞬間消失。

在遊戲的某個關卡裏,平面的第一象限中有n只綠色的小豬,其中第i只小豬所在的坐標為(xi,yi)。

如果某只小鳥的飛行軌跡經過了(xi,yi),那麽第i只小豬就會被消滅掉,同時小鳥將會沿著原先的軌跡繼續飛行;

如果一只小鳥的飛行軌跡沒有經過(xi,yi),那麽這只小鳥飛行的全過程就不會對第i只小豬產生任何影響。

例如,若兩只小豬分別位於(1,3)和(3,3),Kiana可以選擇發射一只飛行軌跡為的小鳥,這樣兩只小豬就會被這只小鳥一起消滅。

而這個遊戲的目的,就是通過發射小鳥消滅所有的小豬。

這款神奇遊戲的每個關卡對Kiana來說都很難,所以Kiana還輸入了一些神秘的指令,使得自己能更輕松地完成這個遊戲。這些指令將在【輸入格式】中詳述。

假設這款遊戲一共有T個關卡,現在Kiana想知道,對於每一個關卡,至少需要發射多少只小鳥才能消滅所有的小豬。由於她不會算,所以希望由你告訴她。

輸入輸出格式

輸入格式:

第一行包含一個正整數T,表示遊戲的關卡總數。

下面依次輸入這T個關卡的信息。每個關卡第一行包含兩個非負整數n,m,分別表示該關卡中的小豬數量和Kiana輸入的神秘指令類型。接下來的n行中,第i行包含兩個正實數(xi,yi),表示第i只小豬坐標為(xi,yi)。數據保證同一個關卡中不存在兩只坐標完全相同的小豬。

如果m=0,表示Kiana輸入了一個沒有任何作用的指令。

如果m=1,則這個關卡將會滿足:至多用只小鳥即可消滅所有小豬。

如果m=2,則這個關卡將會滿足:一定存在一種最優解,其中有一只小鳥消滅了至少只小豬。

保證1<=n<=18,0<=m<=2,0<xi,yi<10,輸入中的實數均保留到小數點後兩位。

上文中,符號和分別表示對c向上取整和向下取整

輸出格式:

對每個關卡依次輸出一行答案。

輸出的每一行包含一個正整數,表示相應的關卡中,消滅所有小豬最少需要的小鳥數量

輸入輸出樣例

輸入樣例#1

2
2 0
1.00 3.00
3.00 3.00
5 2
1.00 5.00
2.00 8.00
3.00 9.00
4.00 8.00
5.00 5.00

輸出樣例#1

1
1

輸入樣例#2

3
2 0
1.41 2.00
1.73 3.00
3 0
1.11 1.41
2.34 1.79
2.98 1.49
5 0
2.72 2.72
2.72 3.14
3.14 2.72
3.14 3.14
5.00 5.00

輸出樣例#2

2
2
3

輸入樣例#3

1
10 0
7.16 6.28
2.02 0.38
8.33 7.78
7.68 2.09
7.46 7.86
5.77 7.44
8.24 6.72
4.42 5.11
5.42 7.79
8.15 4.99

輸出樣例#3

6

說明

【樣例解釋1】

這組數據中一共有兩個關卡。

第一個關卡與【問題描述】中的情形相同,2只小豬分別位於(1.00,3.00)和 (3.00,3.00),只需發射一只飛行軌跡為y = -x^2 + 4x的小鳥即可消滅它們。

第二個關卡中有5只小豬,但經過觀察我們可以發現它們的坐標都在拋物線 y = -x^2 + 6x上,故Kiana只需要發射一只小鳥即可消滅所有小豬。

【數據範圍】

noip2016復賽模擬 未完(現在160分)