The 5th Zhejiang Provincial Collegiate Programming Contest [7月13日暑假集训]
C .Colorful Rainbows [栈与单调性]
N条直线,问有多少条直线能在某x处,其y坐标位于所有直线之上。首先预处理,斜率相同的直线只保留y轴截距最大的。对所有直线按斜率排序,按斜率由小到大处理直线。维护一个栈,当栈中至少有两条直线时,如果当前处理到的直线和栈顶直线的交点横坐标x1,比栈顶直线和栈顶前一条直线交点横坐标x2大,当前直线就入栈,否则栈顶直线出栈,并一直判断下去。最后栈中直线条数就是所求的值。有点卡精度。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
把五个福娃处理成5个01数组。每个数组枚举行r和k,然后判断r行和k行有多少个列是都有福娃的。复杂度O(n^3)。
posted on 2012-07-13 18:32 Lattexiaoyu 阅读(178) 评论(0) 编辑 收藏 举报