zoukankan      html  css  js  c++  java
  • 10.7考试总结

    10.7考试总结


    二分答案专题OwO


    T1

    【问题描述】
    一场地震毁了 Farmer John 的整个农场。他是个有恒心的人,决定
    重建农场。在重建了所有 n( 1<=n<=400)块田野后,他意识到还得
    修路将它们连起来。完工后,任两个田野间必须有路。
    研究了地形后, FJ 认为 m(1<=m<=10000)条双向的道路可能建造。
    由于资金短缺,他希望已尽可能省钱的方式完成整个工程。
    幸运的是,奶牛们已经成立了针对地震后修建农场道路的工程顾
    问公司。奶牛们也很有经济头脑,对没有漂亮利润的工作从不感兴趣。
    奶牛们关心可能的利益。他们已经说定了为修路所获的酬金
    f(1<=f<=2,000,000,000),并得到一张关于可能的道路、修建每条路的
    时 间 ( 以 小 时 计 ) ( 1 <=t<=2,000,000,000 ) 以 及 花 费
    (1<=c<=2000,000,000)的列表。在两块田野间可能有多于一条的道路
    被列出,所给数据总有可以连通所有田野的修路方案,虽然可能无利
    可图。
    确定奶牛修路最高的盈利率。
    输入文件
    第一行三个整数 N, M, F。
    2...M+1 行: 每行四个空格隔开的整数: i, j, c,t 描述两块田夜间的一
    条道路。
    3
    输出文件
    只包含一个数,保留四位小数,奶牛每个小时可以得到的最大利润,
    如果利润非正,输出 0.0000 。
    样例输入 ( quake.in):
    5 5 100
    1 2 20 5
    1 3 20 5
    1 4 20 5
    1 5 20 5
    2 3 23 1
    样例输出( quake.out):
    1.0625
    [奶牛选择建最后四条路,总花费 83 时间 16,他们的筹劳是 100,所
    以他们在 16 各单位时间内得到利润 100-83: 17/16 = 1.0625。

    网上有 并不知道在哪里评测= =
    题目要求(frac{F-sum c_i}{sum t_i})的最大值
    (x=frac{F-sum c_i}{sum t_i}),然后乱搞得(sum t_i imes x=F-sum c_i)
    再乱搞得(F-sum c_i-sum t_i imes x=0)
    (f(x)=F-sum c_i-sum t_i imes x)
    显然这东西是个递减函数= =
    二分(x),然后把边权设成(c_i+t_i imes x),跑一遍最小生成树,把总和与F比一比完事

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #define Fname "quake"
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    #define db long double
    typedef long long ll;
    il int gi(){
        rg int x=0;bool flg=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return flg?-x:x;
    }
    const int maxn=401,maxm=10001;
    int n,m,f;
    struct edge{int a,b,w,t;db v;}e[maxm];
    bool operator < (edge a,edge b){return a.v<b.v;}
    int fa[maxn];
    il int hd(int i){return fa[i]==i?i:hd(fa[i]);}
    il bool check(ll mid){
    	rep(i,1,m)e[i].v=mid/3e6*e[i].t+e[i].w;
    	int x=1;
    	sort(e+1,e+m+1);rep(i,1,n)fa[i]=i;
    	db k=f+1e-12;
    	rep(i,2,n){
    		while(x<=m&&hd(e[x].a)==hd(e[x].b))++x;
    		fa[hd(e[x].a)]=hd(e[x].b),k-=e[x].v;
    		if(k<0)return 0;
    	}return 1;
    }
    int main(){
    	freopen(Fname".in","r",stdin);
    	freopen(Fname".out","w",stdout);
    	n=gi(),m=gi(),f=gi();
    	rep(i,1,m)e[i].a=gi(),e[i].b=gi(),e[i].w=gi(),e[i].t=gi();
    	if(!check(0ll)){puts("0.0000");return 0;}
    	ll mid,l=0,r=2e15;
    	while(l<r){
    		mid=(l+r)>>1;
    		if(check(mid+1))l=mid+1;
    		else r=mid;
    	}printf("%.4Lf
    ",l/(db)3e6);
    	return 0;
    }
    

    Ps.mdzz卡精度大狗题。。。


    T2

    http://www.lydsy.com/JudgeOnline/problem.php?id=1816

    二分+1
    二分一下几副牌,然后要加的joker数量为(sum max(mid-c[i],0))
    加的joker最多(min(m,mid))个。判断一下下

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #define Fname "cards"
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    typedef long long ll;
    il ll gi(){
        rg ll x=0;bool flg=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return flg?-x:x;
    }
    ll c[52],n,m;
    il bool check(const ll&mid){
    	ll tot=0;
    	rep(i,1,n)tot+=max(0ll,mid-c[i]);
    	return tot<=min(m,mid);
    }
    int main(){
        freopen(Fname".in","r",stdin);
        freopen(Fname".out","w",stdout);
    	n=gi(),m=gi();
    	ll mid,l=0,r=2e9;
    	rep(i,1,n)c[i]=gi();
    	while(l<r){
    		mid=(l+r)>>1;
    		if(check(mid+1))l=mid+1;
    		else r=mid;
    	}printf("%lld
    ",l);
        return 0;
    }
    

    T3

    https://www.luogu.org/problem/show?pid=3199#sub
    有向图最小圈。
    要求的是(frac{sum C_i}{k})最小值
    依然令(x=frac{sum C_i}{k})
    (k imes x=sum C_i)
    (sum_{i=1}^{k} C_i-k imes x=0)
    (sum C_i - x=0)
    如果(sum C_i -x <0)的话,图就有负环了= =二分(x),用神搜四把法搞搞。

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define Fname "cycle"
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    typedef long long ll;
    il int gi(){
        rg int x=0;bool flg=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return flg?-x:x;
    }
    #define db long double
    il db gf(){static db a;scanf("%Lf",&a);return a;}
    const int maxn=3010,maxm=10010;
    int n,m,s,fir[maxn],dis[maxm],nxt[maxm],id;db w[maxm];
    il vd add(int a,int b,db c){nxt[++id]=fir[a],dis[id]=b,fir[a]=id,w[id]=c;}
    db dist[maxn];bool flg=0;
    bool vis[maxn];
    il vd spfa(const int &x){
    	vis[x]=1;
    	erep(i,x)if(dist[dis[i]]>dist[x]+w[i]){
    		dist[dis[i]]=dist[x]+w[i];
    		if(flg||vis[dis[i]]){flg=1;break;}
    		spfa(dis[i]);
    	}
    	vis[x]=0;
    }
    il bool check(ll a){
    	rep(i,1,id)w[i]-=a/1e9-(1e-16);
    	rep(i,1,n)dist[i]=0,vis[i]=0;
    	flg=0;
    	rep(i,1,n){
    		spfa(i);
    		if(flg)break;
    	}
    	rep(i,1,id)w[i]+=a/1e9-(1e-16);
    	return !flg;
    }
    int __sum;
    il vd dfs(const int&x){vis[x]=1,++__sum;erep(i,x)if(!vis[dis[i]])dfs(dis[i]);}
    int main(){
    	freopen(Fname".in","r",stdin);
    	freopen(Fname".out","w",stdout);
    	n=gi(),m=gi();
    	int a,b;db c;
    	while(m--)a=gi(),b=gi(),c=gf(),add(a,b,c);
    	ll l=-1e16,r=1e16,mid;
    	rep(i,1,n){
    		memset(vis,0,sizeof vis);
    		__sum=0;dfs(i);
    		if(__sum==n){s=i;break;}
    	}
    	while(l<r){
    		mid=((l+r)>>1)+1;
    		if(check(mid))l=mid;
    		else r=mid-1;
    	}
    	printf("%.8lf
    ",l/1e9);
    	return 0;
    }
    

    STO dsl AK OTZ

  • 相关阅读:
    oracle:数据库对象:创建用户和赋予权限,数据表,序列,事务,约束
    oracle:多表关联 join on,单行子查询,多行子查询,TOP-N,行转列
    oracle:数值型函数,日期函数,转换函数,decode/case when条件判断,组函数,分组group by,排序order by,两表查询连接
    informix建临时表索引
    jbpm4.3表结构和表字段说明
    JBPM4 常用表结构及其说明
    Docker技术学习
    千万PV级别WEB站点架构设计
    四层和七层负载均衡的区别
    STORM在线业务实践-集群空闲CPU飙高问题排查
  • 原文地址:https://www.cnblogs.com/xzz_233/p/7635727.html
Copyright © 2011-2022 走看看