XJOI网上同步训练DAY1 T1

思路:我们考虑由于没有人的区间会覆盖其他人,所以我们将区间按左端点排序,发现如果地盘长度已知,可以贪心地尽量往左放,来判断是否有解,因此做法很简单,就是二分答案,然后O(n)贪心判定,复杂度为O(nlogn)

满分程序:

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define ll long long
 7 const long double eps=1e-12;
 8 int n;
 9 struct node{
10     long double l,r;
11 }a[200005];
12 bool cmp(node q,node w){
13     if (q.l==w.l) return q.r<w.r;
14     return q.l<w.l;
15 }
16 int read(){
17     char ch=getchar();int t=0,f=1;
18     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
19     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
20     return t*f;
21 }
22 bool check(long double mid){
23     long double last=0,len=0;
24     for (int i=1;i<=n;i++){
25         len=std::max(a[i].r-std::max(a[i].l,last),(long double)0.0);
26         if (len<mid) return 0;
27         last=std::max(a[i].l,last)+mid;
28     }
29     return 1;
30 }
31 ll gcd(ll a,ll b){
32     if (b==0) return a;
33     else return gcd(b,a%b);
34 }
35 void getpq(long double x,ll &p,ll &q){
36     long double mod=1e8,tmp;
37     p=0,q=0;
38     for (int i=1;i<=n;i++){
39         tmp=fabs(x*i-(ll)(x*i+.5));
40         if (tmp<mod)
41          mod=tmp,q=i,p=(ll)(x*i+.5);
42     }
43     ll t=gcd(p,q);
44     p/=t;
45     q/=t;
46 }
47 int main(){
48     int T=read();
49     while (T--){
50         n=read();
51         for (int i=1;i<=n;i++)
52          a[i].l=read(),a[i].r=read();
53         std::sort(a+1,a+1+n,cmp);
54         long double l=0,r=1e8;
55         while (r-l>eps){
56             long double mid=(l+r)/2;
57             if (check(mid)) l=mid;
58             else r=mid;
59         } 
60         ll p,q;
61         getpq(l,p,q);
62         printf("%lld/%lld
",p,q);
63     }
64 }

注意:

(1)没开longdouble,这个错误率好像比较小。。

(2)eps开的不够小,这很可能WA

(3)输出的时候,有没有和其他的方案比较一下,谁的误差比较小。

真是个惨痛的教训。。。T_T

原文地址:https://www.cnblogs.com/qzqzgfy/p/5614127.html