标签:struct ati 整数 连通 二次 布局 load 比较 token
农夫约翰建造了一座有n间牛舍的小屋,牛舍排在一条直线上,第i间牛舍在xi的位置,但是约翰的m头牛对小屋很不满意,因此经常互相攻击。约翰为了防止牛之间互相伤害,因此决定把每头牛都放在离其它牛尽可能远的牛舍。也就是要最大化最近的两头牛之间的距离。
牛们并不喜欢这种布局,而且几头牛放在一个隔间里,它们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是多少呢?
5 3
1 2 8 4 9
3
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+7; int a[N],n,m; bool check(int x){ int t=a[0]; int cnt=1; for(int i=1;i<n;i++) if(a[i]-t>=x){ cnt++; t=a[i]; if(cnt>=m) return true; } return false; } int main(){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); int l=0,r=a[n-1]-a[0]; while(l<=r){ int mid=l+r>>1; if(check(mid)) l=mid+1; else r=mid-1; } cout<<r<<endl; return 0; }
给定一个长度为n的正整数序列A,求一个平均数最大的,长度不小于L的子段。
10 6
6 4 2 10 3 8 5 9 4 1
6500
#pragma GCC optimize(2) #include<bits/stdc++.h> #define inf 0x3f3f3f3f typedef long long ll; using namespace std; const int N=1e6+7; ll a[N],n,m; ll sum[N];//前缀和 bool check(ll x){ for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]-x; ll minn=inf; for(int i=m;i<=n;i++){ minn=min(minn,sum[i-m]); if(sum[i]-minn>=0) return true; } return false; } int main(){ scanf("%d%d",&n,&m); ll l,r; for(int i=1;i<=n;i++){ cin>>a[i]; a[i]*=1000; l=min(l,a[i]); r=max(r,a[i]); } ll res; while(l<=r){ ll mid=l+r>>1; if(check(mid)) res=mid,l=mid+1; else r=mid-1; } //res*=1000; cout<<res<<endl; return 0; }
明明做作业的时候遇到了n个二次函数Si(x)=ax2+bx+c,他突发奇想设计了一个新的函数F(x)=max{Si(x)},i=1…n。
明明现在想求这个函数在[0,1000]的最小值,要求精确到小数点后四位,四舍五入。
2
1
2 0 0
2
2 0 0
2 -4 2
0.0000
0.5000
#pragma GCC optimize(2) #include<bits/stdc++.h> #define inf 0x3f3f3f3f typedef long long ll; using namespace std; const int N=1e6+7; int a[N],b[N],c[N],n; //最小值 double check(double x){ double minn=-inf; for(int i=1;i<=n;i++) minn=max(minn,a[i]*x*x+b[i]*x+c[i]); return minn; } int main(){ int t; cin>>t; while(t--){ cin>>n; for(int i=1;i<=n;i++) cin>>a[i]>>b[i]>>c[i]; double l=0,r=1000; while(r-l>=1e-10){ double mid1=l+(r-l)/3,mid2=r-(r-l)/3; if(check(mid1)>check(mid2)) l=mid1; else r=mid2; } printf("%.4lf\n",check(l)); } return 0; }
对于给定的一个长度为N的正整数数列A,现要将其分成M段,并要求每段连续,且每段和的最大值最小。
例如,将数列4 2 4 5 1要分成3段:
若分为[4 2][4 5][1],各段的和分别为6,9,1,和的最大值为9;
若分为[4][2 4] [5 1],各段的和分别为4,6,6,和的最大值为6;
并且无论如何分段,最大值不会小于6。
所以可以得到要将数列4 2 4 5 1要分成3段,每段和的最大值最小为6。
5 3
4 2 4 5 1
6
#pragma GCC optimize(2) #include<bits/stdc++.h> #define inf 0x3f3f3f3f typedef long long ll; using namespace std; const int N=1e6+7; ll n,m,a[N]; //每段和最大值最小 bool check(ll x){ ll sum=0,cnt=1; for(int i=1;i<=n;i++){ if(sum+a[i]>x){ sum=a[i]; cnt++; } else sum+=a[i]; } if(cnt<=m) return true; else return false; } int main(){ scanf("%lld%lld",&n,&m); ll l=-inf,r=0; for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); l=max(l,a[i]); r+=a[i]; } ll res; while(l<=r){ ll mid=l+r>>1; if(check(mid)) res=mid,r=mid-1; else l=mid+1; } cout<<res<<endl; return 0; }
相比 wildleopard 的家,他的弟弟 mildleopard 比较穷。他的房子是狭窄的而且在他的房间里面仅有一个灯泡。每天晚上,他徘徊在自己狭小的房子里,思考如何赚更多的钱。有一天,他发现他的影子的长度随着他在灯泡和墙壁之间走到时发生着变化。一个突然的想法出现在脑海里,他想知道他的影子的最大长度。
3
2 1 0.5
2 0.5 3
4 3 4
1.000
0.750
4.000
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; double H,h,D; typedef long long ll; double check(double x){ if(-x-(H-h)*D/x+D+H < 0) return 0; return (-x-(H-h)*D/x+D+H); } int main(){ int t; cin>>t; while(t--){ cin>>H>>h>>D; double l=(H-h)*D/H,r=D; while(r-l>=1e-10){ double mid1=l+(r-l)/3,mid2=r-(r-l)/3; if(check(mid1)>check(mid2)) r=mid2; else l=mid1; } printf("%.3lf\n",check(l)); } return 0; }
#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int N=55; struct node{ int x,y; }a[N]; int d[N][N],fa[N],n; int dis(node a,node b){ return abs(a.x-b.x)+abs(a.y-b.y); } int ffind(int x){ x==fa[x]?x:fa[x]=ffind(fa[x]); } void unionn(int x,int y){ int fx=ffind(x),fy=ffind(y); if(fx!=fy) fa[fx]=fy; } //两个点垂直距离+水平距离<=2*t 这两个点就会相遇 bool check(int x){ for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(d[i][j]<=x*2) unionn(i,j); int sum=0; for(int i=1;i<=n;i++){ if(fa[i]==i) sum++; if(sum==2) return false; } return true; } int main(){ cin>>n; for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=dis(a[i],a[j]); int l=0,r=inf,ans; while(l<=r){ int mid=l+r>>1; if(check(mid)) ans=mid,r=mid-1; else l=mid+1; } cout<<ans<<endl; return 0; }
在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间
0 0 0 100
100 0 100 100
2 2 1
136.60
#include<bits/stdc++.h> using namespace std; double xa,ya,xb,yb,xc,yc,xd,yd,p,q,r; double dis(double x1,double y1,double x2,double y2){ //return fabs(x1-x2)+fabs(y1-y2); return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } double check(double x,double y){ double xl=xc,yl=yc,xr=xd,yr=yd; while(fabs(xr-xl)>1e-8||fabs(yr-yl)>1e-8){ double xmid1=xl+(xr-xl)/3,ymid1=yl+(yr-yl)/3; double xmid2=xr-(xr-xl)/3,ymid2=yr-(yr-yl)/3; double t1=dis(xa,ya,x,y)/p+dis(x,y,xmid1,ymid1)/r+dis(xmid1,ymid1,xd,yd)/q; double t2=dis(xa,ya,x,y)/p+dis(x,y,xmid2,ymid2)/r+dis(xmid2,ymid2,xd,yd)/q; if(t1<t2) xr=xmid2,yr=ymid2; else xl=xmid1,yl=ymid1; } return dis(xa,ya,x,y)/p+dis(x,y,xl,yl)/r+dis(xl,yl,xd,yd)/q; } int main(){ cin>>xa>>ya>>xb>>yb>>xc>>yc>>xd>>yd>>p>>q>>r; double xl=xa,yl=ya,xr=xb,yr=yb; while(fabs(xr-xl)>1e-8||fabs(yr-yl)>1e-8){ double xmid1=xl+(xr-xl)/3,ymid1=yl+(yr-yl)/3; double xmid2=xr-(xr-xl)/3,ymid2=yr-(yr-yl)/3; if(check(xmid1,ymid1)<check(xmid2,ymid2)) xr=xmid2,yr=ymid2; else xl=xmid1,yl=ymid1; } printf("%.2lf",check(xl,yl)); return 0; }
标签:struct ati 整数 连通 二次 布局 load 比较 token
原文地址:https://www.cnblogs.com/Cutele/p/12242983.html