1. 程式人生 > >北京集訓DAY4

北京集訓DAY4

pac cst 斜率 turn ons 一個 交點 for --

技術分享

技術分享
 1 /*
 2     單調隊列 
 3     從左向右 每個點向右找一最近的且比他大,
 4     從右往左枚舉過來 每個點 向左找最近的且比他大
 5 */
 6 #include <cmath>
 7 #include <cstdio>
 8 #include <cstdlib>
 9 #include <iostream>
10 #include <algorithm>
11 using namespace std;
12 int n,s[50002],d[50002],ans[50002],ANS,a[50002],b[50002
],r,i; 13 int main() 14 { 15 freopen("treasure.in","r",stdin); 16 freopen("treasure.out","w",stdout); 17 cin>>n; 18 for (i=1; i<=n; i++) scanf("%d%d",&a[i],&b[i]); 19 s[1]=a[1]; d[1]=1; r=1; 20 for (i=2; i<=n; i++) 21 { 22 while (r!=0 && a[i]>s[r]) { ans[i]+=b[d[r]]; r--; }
23 r++; 24 s[r]=a[i]; 25 d[r]=i; 26 } 27 s[1]=a[n]; d[1]=n; r=1; 28 for (i=n-1; i>=1; i--) 29 { 30 while (r!=0 && a[i]>s[r]) { ans[i]+=b[d[r]]; r--; } 31 r++; 32 s[r]=a[i]; 33 d[r]=i; 34 } 35 for (i=1
; i<=n; i++) ANS=max(ANS,ans[i]); 36 cout<<ANS; 37 return 0; 38 }
代碼

技術分享

技術分享
 1 /*
 2     答案是連續的。
 3     如果邊長為x可行,邊長x+1也一定能覆蓋至少C個糖果    
 4     假如x不可行,邊長為x-1是不可能覆蓋C個糖果的。
 5     二分答案。
 6     l=1,r=10000,  判斷mid是否可行,  可行->  答案在[l,mid] ,不可行 -> (mid,r]
 7 */
 8 #include <cmath>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 struct node {int x,y;} a[1005];
15 int C,n,L,R,mid,b[1005],o,i;
16 int cmp(node i,node j) {return i.x<j.x;}
17 int CMP(int i,int j) {return i<j;}
18 bool WORK(int l,int r)
19 {
20      if (r-l+1<C) return false; o=0;
21      for (int i=l; i<=r; i++) b[++o]=a[i].y;
22      sort(b+1,b+o+1,CMP);
23      for (int i=C; i<=o; i++)
24        if (b[i]-b[i-C+1]<=mid) return true;
25       return false;
26 }
27 bool OK(int x)
28 {
29     int l=1;
30     for (int i=1; i<=n; i++)
31     {
32         if (a[i].x-a[l].x>x)
33         {
34                              if (WORK(l,i-1)) return true;
35                              while (a[i].x-a[l].x>x) l++;
36         }
37     }
38     if (WORK(l,n)) return true;
39     return false;
40 }
41 int main()
42 {
43     freopen("square.in","r",stdin);
44     freopen("square.out","w",stdout);
45     scanf("%d%d",&C,&n);
46     for (i=1; i<=n; i++)
47         scanf("%d%d",&a[i].x,&a[i].y);
48     sort(a+1,a+n+1,cmp);
49     L=0; R=10000; mid=(L+R)/2;
50     while (L<=R)
51     {
52           if (OK(mid)) {R=mid-1; mid=(L+R)/2;} else
53           {
54                        L=mid+1;
55                        mid=(L+R)/2;
56           }
57     }
58     cout<<L+1;
59     return 0;
60 }
代碼

技術分享

技術分享
 1 /*
 2     求出一個上圖像和一個下圖像,中間既不是最大值
 3     圖像的交點,又不是最小值直線的交點,可以扔掉。
 4     斜率大的(速度大的),肯定最終到上面。所以我們按
 5     斜率進行排序,排序後插入圖像(從小到大),將屬於
 6     自己的位置求出,同理,下圖像也可以求出。讓上圖
 7     像和下圖像不斷移動,即可求出。
 8     相當於單調棧。(右圖中沒有畫圈的交點可以扔掉。)
 9     這道題一開始保證跑的慢的豹子一定先跑,跑的快的
10     豹子一定後跑。
11     我們只需要記錄最上方那條線和最下方那條線
12     被哪個豹子保管。
13     用 f[i]表示第 i 只豹子保管了哪個區間。
14 */
15 #include<cstdio>
16 #include<cstring>
17 #include<cstdlib>
18 #include<cmath>
19 #include<iostream>
20 #include<algorithm>
21 
22 using namespace std;
23 const long double INF=(long double)1000000000*10;
24 long double L,R,mid,ans,hh[100005];
25 int r,rr,i,n,MAX,X,Y,cnt,vv[100005],vv2[100005];
26 struct node2 {int t; long double l;} s[200005],S[200005];
27 struct node {int t,v;} t[100005];
28 int cmp(node i,node j) {return i.v<j.v || i.v==j.v && i.t>j.t;}
29 struct Node {long double x;int y,z;} p[200005];
30 int CMP(Node i,Node j) {return i.x<j.x;}
31 long double work(int x,long double y) {return (long double)t[x].v*y-hh[x];}
32 int main()
33 {
34     freopen("chase.in","r",stdin);
35     freopen("chase.out","w",stdout);
36     while (1)
37     {
38         scanf("%d",&n);
39        // if (n==0) return 0;
40         MAX=0;
41         for (i=1; i<=n; i++)
42         {
43             scanf("%d%d",&t[i].t,&t[i].v);
44             MAX=max(MAX,t[i].t);
45         }
46         sort(t+1,t+n+1,cmp); int MIN=t[n].t;
47         for (i=n-1; i>=2; i--)
48         {
49             if (t[i].t>MIN) vv[i]=1; else
50             MIN=t[i].t,vv[i]=0;
51         }
52         for (i=1; i<=n; i++) hh[i]=(long double)t[i].t*t[i].v;
53         r=1; s[1].l=MAX; s[1].t=1; s[2].l=INF; vv[n]=0;
54         for (i=2; i<=n; i++)
55         if (!vv[i])
56         {
57             while (r && work(i,s[r].l)>=work(s[r].t,s[r].l)) r--;
58             if (!r) {r=1; s[1].l=MAX; s[1].t=i; continue;}
59             L=s[r].l; R=s[r+1].l; mid=(L+R)/2.0;
60             for (int I=1; I<=80; I++)
61             {
62                 if (work(i,mid)>=work(s[r].t,mid)) {R=mid; mid=(L+R)/2.0;} else {L=mid; mid=(L+R)/2.0;}
63             }
64             s[++r].l=mid; s[r].t=i; s[r+1].l=INF;
65         }
66         rr=1; S[1].l=MAX; S[2].l=INF; S[1].t=n;
67         MIN=t[1].t;
68         for (i=2; i<n; i++)
69           if (t[i].t<MIN) vv2[i]=1; else
70             MIN=t[i].t,vv2[i]=0;
71         for (i=n-1; i>=1; i--)
72         if (!vv2[i])
73         {
74             while (rr && work(i,S[rr].l)<=work(S[rr].t,S[rr].l)) rr--;
75             if (!rr) {rr=1; S[1].l=MAX; S[1].t=i; continue;}
76             L=S[rr].l; R=S[rr+1].l; mid=(L+R)/2.0;
77             for (int I=1; I<=80; I++)
78             {
79                 if (work(i,mid)<=work(S[rr].t,mid)) {R=mid; mid=(L+R)/2.0;} else {L=mid; mid=(L+R)/2.0;}
80             }
81             S[++rr].l=mid; S[rr].t=i; S[rr+1].l=INF;
82         }
83         cnt=0;
84         for (i=1; i<=r; i++) {p[++cnt].x=s[i].l; p[cnt].y=1; p[cnt].z=s[i].t;}
85         for (i=1; i<=rr; i++) {p[++cnt].x=S[i].l; p[cnt].y=0; p[cnt].z=S[i].t;}
86         sort(p+1,p+cnt+1,CMP); X=Y=0; ans=INF;
87         for (i=1; i<=cnt; i++)
88         {
89             if (p[i].y==1) X=p[i].z; else Y=p[i].z;
90           //  printf("%.5f\n",(double)p[i].x);
91             if (X && Y) ans=min(ans,work(X,p[i].x)-work(Y,p[i].x));
92         }
93         printf("%.2f\n",fabs((double)ans));
94         return 0;
95     }
96 }
代碼

北京集訓DAY4