The 5th Zhejiang Provincial Collegiate Programming Contest [7月13日暑假集训]

C .Colorful Rainbows  [栈与单调性]

  N条直线,问有多少条直线能在某x处,其y坐标位于所有直线之上。首先预处理,斜率相同的直线只保留y轴截距最大的。对所有直线按斜率排序,按斜率由小到大处理直线。维护一个栈,当栈中至少有两条直线时,如果当前处理到的直线和栈顶直线的交点横坐标x1,比栈顶直线和栈顶前一条直线交点横坐标x2大,当前直线就入栈,否则栈顶直线出栈,并一直判断下去。最后栈中直线条数就是所求的值。有点卡精度。

 

View Code
 1 //zzy2012AC
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<string>
 6 #include<cmath>
 7 #include<iostream>
 8 #include<algorithm>
 9 #include<map>
10 #include<vector>
11 #include<queue>
12 #define sf scanf
13 #define pf printf
14 #define pfn printf("\n");
15 #define ll long long
16 #define INF 0x7fffffff
17 
18 using namespace std;
19 
20 typedef struct dnode{
21     double a,b,locb,loca;
22     int color;
23     friend bool operator <(struct dnode n1,struct dnode n2){
24         if(n1.a < n2.a)
25             return true;
26         else if(fabs(n1.a - n2.a)<1.0e-6)
27             return (n1.b > n2.b);
28         return false;
29     }
30 }node;
31 
32 int n,ans;
33 node line[5001],tt[5001];
34 
35 void E(){
36     for(int i=0; i<n-1; i++){
37         if(fabs(tt[i].a - tt[i+1].a)<1.0e-6){
38             tt[i+1].color = 1;
39         }
40     }
41     int m = 0;
42     for(int i=0; i<n; i++){
43         if(tt[i].color == 0)
44             line[m++] = tt[i];
45     }
46     n = m;
47 }
48 
49 void D(){
50     ans = 0;
51     double loca,locb;
52     for(int i=0; i<n; i++){
53         if(ans == 0){
54             tt[ans++] = line[i];
55         }
56         else if(ans == 1){
57             tt[ans] = line[i];
58             tt[ans].loca = line[i].a - tt[0].a;
59             tt[ans].locb = tt[0].b - line[i].b;
60             ans++;
61         }
62         else{
63             loca = line[i].a - tt[ans-1].a;
64             locb = tt[ans-1].b - line[i].b;
65             while(ans>1 && (tt[ans-1].loca*locb)<=tt[ans-1].locb*loca){
66                 ans--;
67                 loca = line[i].a - tt[ans-1].a;
68                 locb = tt[ans-1].b - line[i].b;
69             }
70             tt[ans] = line[i];
71             tt[ans].loca = tt[ans].a - tt[ans-1].a;
72             tt[ans].locb = tt[ans-1].b - tt[ans].b;
73             ans++;
74         }
75     }
76 }
77 
78 int main()
79 {
80     int T;
81     cin>>T;
82     while(T--){
83         cin>>n;
84         for(int i=0; i<n; i++){
85             sf("%lf %lf",&tt[i].a,&tt[i].b);
86             tt[i].color = 0;
87         }
88         sort(tt,tt+n);
89         E();
90         ans = 0;
91         D();
92         pf("%d\n",ans);
93     }
94     return 0;
95 }

 

 

 

E .Easy Task

  直接根据多项式求导公式加特判。

K .Kinds of Fuwas

  把五个福娃处理成501数组。每个数组枚举行rk,然后判断r行和k行有多少个列是都有福娃的。复杂度O(n^3)

posted on 2012-07-13 18:32  Lattexiaoyu  阅读(178)  评论(0编辑  收藏  举报

导航