2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017)
A. Airport Coffee
设$f_i$表示考虑前$i$个咖啡厅,且在$i$处买咖啡的最小时间,通过单调队列优化转移。
时间复杂度$O(n)$。
#include<cstdio> const int N=500010; typedef long long ll; const double inf=1e20; ll L,A,B,T,R,lim0,lim1,a[N]; double f[N],val[N]; double dp0=inf; int id0; int pre[N]; int i,j,k; int h=1,t,q[N]; double ans; int fin; int cof[N],cnt,n; int main(){ scanf("%lld%lld%lld%lld%lld",&L,&A,&B,&T,&R); lim0=A*T+R*B; lim1=T*A; scanf("%d",&n); for(i=1;i<=n;i++)scanf("%lld",&a[i]); ans=1.0*L/A; for(i=j=k=1;i<=n;i++){ f[i]=1.0*a[i]/A; while(j<i&&a[i]-a[j]>=lim0){ double now=f[j]-1.0*a[j]/A; if(now<dp0){ dp0=now; id0=j; } j++; } if(id0){ double now=dp0+1.0*(a[i]-lim0)/A+T+R; if(now<f[i]){ f[i]=now; pre[i]=id0; } } while(k<i&&a[i]-a[k]>=lim1){ val[k]=f[k]-1.0*a[k]/B; while(h<=t&&val[q[t]]>val[k])t--; q[++t]=k; k++; } while(h<=t&&a[i]-a[q[h]]>=lim0)h++; if(h<=t){ double now=val[q[h]]+1.0*(a[i]-lim1)/B+T; if(now<f[i]){ f[i]=now; pre[i]=q[h]; } } double ret=f[i]; ll d=L-a[i]; if(d<=lim1){ ret+=1.0*d/A; }else if(d<=lim0){ ret+=1.0*(d-lim1)/B+T; }else{ ret+=1.0*(d-lim0)/A+T+R; } if(ret<ans){ ans=ret; fin=i; } } while(fin){ cof[++cnt]=fin; fin=pre[fin]; } printf("%d\n",cnt); for(i=cnt;i;i--)printf("%d ",cof[i]-1); } //0 .. n-1
B. Best Relay Team
按题意模拟即可。
#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math.h> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre() { } #define MS(x, y) memset(x, y, sizeof(x)) #define MC(x, y) memcpy(x, y, sizeof(x)) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; } template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; } const int N = 1010, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f; template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; } int casenum, casei; int l, r; struct A { string s; double fi, se; }a[N], b[N]; int n; string ss[5]; bool cmp(A a, A b) { return a.se < b.se; } int main() { scanf("%d", &n); for(int i = 1; i <= n; i ++){ cin >> a[i].s; scanf("%lf%lf", &a[i].fi, &a[i].se); a[i + n] = a[i]; } double ans = 1e9; for(int i = 1; i <= n; i ++){ MC(b, a); sort(b + i + 1, b + n + i, cmp); double tmp = b[i].fi + b[i + 1].se + b[i + 2].se + b[i + 3].se; if(tmp < ans){ ans = tmp; ss[1] = b[i].s; ss[2] = b[i + 1].s; ss[3] = b[i + 2].s; ss[4] = b[i + 3].s; } } printf("%.2f\n", ans); for(int i = 1; i <= 4; i ++){ //printf("%s\n", ss[i]); cout << ss[i] << endl; } scanf("%d", &n); return 0; } /* 【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */
C. Compass Card Sales
按题意模拟即可。
#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math.h> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre() { } #define MS(x, y) memset(x, y, sizeof(x)) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; } template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; } const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f; template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; } int casenum, casei; int n; struct A { int v[3]; int id; int val; }a[N];// keep a not modified struct B { int id; int val; bool operator < (const B & b)const { if(val != b.val)return val < b.val; return id > b.id; } }; set<int>sot[3][720]; set<B>b; //use the a[o] int getval(int o) { int val = 0; for(int i = 0; i < 3; ++i) { int pos = a[o].v[i]; if(sot[i][pos].size() >= 2) { continue; } int pre = pos + 360; do { --pre; }while(!sot[i][pre].size()); int suf = pos; do { ++suf; }while(!sot[i][suf].size()); val += (pos + 360 - pre) + (suf - pos); } //printf("o = %d a[o].id = %d a[o].val = %d\n", o, a[o].id, val); return val; } map<int, int>mop; int main() { while(~scanf("%d",&n)) { mop.clear(); for(int i = 0; i < 3; ++i) { for(int j = 0; j < 720; ++j) { sot[i][j].clear(); } } b.clear(); for(int i = 1; i <= n; ++i) { for(int j = 0; j < 3; ++j) { scanf("%d", &a[i].v[j]); } scanf("%d", &a[i].id); mop[a[i].id] = i; for(int j = 0; j < 3; ++j) { int p = a[i].v[j]; int o = a[i].id; sot[j][p].insert(o); sot[j][p + 360].insert(o); } } //a index is a input order for(int i = 1; i <= n; ++i) { a[i].val = getval(i); b.insert({a[i].id, a[i].val}); } while(n--) { int id = b.begin()->id; int o = mop[id]; printf("%d\n", id); b.erase({id, a[o].val}); for(int i = 0; i < 3; ++i) { int pos = a[o].v[i]; sot[i][pos].erase(id); sot[i][pos + 360].erase(id); } for(int i = 0; i < 3; ++i) { int pos = a[o].v[i]; if(sot[i][pos].size() == 1) { int rst = mop[*sot[i][pos].begin()]; b.erase({a[rst].id, a[rst].val}); a[rst].val = getval(rst); b.insert({a[rst].id, a[rst].val}); } else if(sot[i][pos].size() == 0 && n > 1) { int pos = a[o].v[i]; int pre = pos + 360; do { --pre; }while(!sot[i][pre].size()); if(sot[i][pre].size() == 1) { int rst = mop[*sot[i][pre].begin()]; b.erase({a[rst].id, a[rst].val}); a[rst].val = getval(rst); b.insert({a[rst].id, a[rst].val}); } int suf = pos; do { ++suf; }while(!sot[i][suf].size()); if(sot[i][suf].size() == 1) { int rst = mop[*sot[i][suf].begin()]; b.erase({a[rst].id, a[rst].val}); a[rst].val = getval(rst); b.insert({a[rst].id, a[rst].val}); } } } } } return 0; } /* 【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */
D. Distinctive Character
设$f_S$表示到$S$的最大相似度,显然对于输入的$n$个串$a_i$,有$f_{a_i}=k$。
对于$f_S=k$,将$S$修改一位,可以得到$f_{S'}=k-1$,BFS求出所有$S$即可。
时间复杂度$O(k2^k)$。
#include<cstdio> int n,m,i,h,t,f[1<<20],q[2222222],x,y; char s[100]; inline void ext(int x,int y){if(f[x]<0)f[q[++t]=x]=y;} int main(){ scanf("%d%d",&n,&m); for(i=0;i<1<<m;i++)f[i]=-1; while(n--){ scanf("%s",s); int t=0; for(i=0;i<m;i++)t=t*2+s[i]-'0'; f[t]=m; } h=1; for(i=0;i<1<<m;i++)if(~f[i])q[++t]=i; while(h<=t){ x=q[h++]; y=f[x]-1; for(i=0;i<m;i++)ext(x^(1<<i),y); } for(i=m-1;~i;i--)printf("%d",x>>i&1); }
E. Emptying the Baltic
令两点间的边权为较大的高度,求出最小生成树,则每个点的实际水位为起点到它路径上点权的最大值。
#include<cstdio> #include<algorithm> using namespace std; const int N=550,M=N*N; int n,m,i,j,x,y,tot,id[N][N],a[M],f[M]; int ce; int v[M*2],nxt[M*2],ed,g[M]; long long ans; struct E{int x,y,z;E(){}E(int _x,int _y,int _z){x=_x,y=_y,z=_z;}}e[M*9]; inline bool cmp(const E&a,const E&b){return a.z<b.z;} int F(int x){return f[x]==x?x:f[x]=F(f[x]);} inline void add(int x,int y){ v[++ed]=y;nxt[ed]=g[x];g[x]=ed; } void dfs(int x,int y,int z){ z=max(z,a[x]); if(z<0)ans-=z; for(int i=g[x];i;i=nxt[i])if(v[i]!=y)dfs(v[i],x,z); } int main(){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++)for(j=1;j<=m;j++){ id[i][j]=++tot; scanf("%d",&a[tot]); } for(i=1;i<=n;i++)for(j=1;j<=m;j++)for(x=-1;x<=1;x++)for(y=-1;y<=1;y++){ int nx=i+x,ny=j+y; if(nx<1||nx>n||ny<1||ny>m)continue; e[++ce]=E(id[i][j],id[nx][ny],max(a[id[i][j]],a[id[nx][ny]])); } sort(e+1,e+ce+1,cmp); for(i=1;i<=tot;i++)f[i]=i; for(i=1;i<=ce;i++)if(F(e[i].x)!=F(e[i].y)){ f[f[e[i].x]]=f[e[i].y]; add(e[i].x,e[i].y); add(e[i].y,e[i].x); } scanf("%d%d",&i,&j); dfs(id[i][j],0,-10000000); printf("%lld",ans); }
F. Fractal Tree
留坑。
G. Galactic Collegiate Programming Contest
用一个set维护所有严格比$1$好的队伍,若别人过题则试情况插入set,若$1$过题则将set中最差的若干队伍删除。
#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math.h> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre() { } #define MS(x, y) memset(x, y, sizeof(x)) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; } template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; } const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f; template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; } int casenum, casei; int n, m; struct A { int g, t; bool operator < (const A &b)const { if(g != b.g)return g > b.g; return t < b.t; } }a[N]; multiset<A>sot; int main() { while(~scanf("%d%d",&n, &m)) { for(int i = 1; i <= n; ++i) { a[i].g = a[i].t = 0; } for(int i = 1; i <= m; ++i) { int o, p; scanf("%d%d", &o, &p); if(o == 1) { a[1].g += 1; a[1].t += p; } else { if(a[o] < a[1]) { sot.erase(sot.find(a[o])); } a[o].g += 1; a[o].t += p; sot.insert(a[o]); } while(!sot.empty() && !(*--sot.end() < a[1])) { sot.erase(--sot.end()); } printf("%d\n", sot.size() + 1); } } return 0; } /* 【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */
H. Hubtown
极角排序后求出每个人最近的$1$到$2$条火车线路,然后求最大流即可。
#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math.h> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre() { } #define MS(x, y) memset(x, y, sizeof(x)) #define ls o<<1 #define rs o<<1|1 typedef long long ll; typedef unsigned long long UL; typedef unsigned int UI; template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; } template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; } const int N = 4e5 + 10, M = 2e6 + 10, Z = 1e9 + 7, inf = 0x3f3f3f3f; template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; } int casenum, casei; int n, m; int ST, ED, ID; int first[N], w[M], cap[M], nxt[M]; void ins(int x, int y, int cap_) { w[++ID] = y; cap[ID] = cap_; nxt[ID] = first[x]; first[x] = ID; w[++ID] = x; cap[ID] = 0; nxt[ID] = first[y]; first[y] = ID; } int d[N]; bool bfs() { MS(d, -1); d[ST] = 0; queue<int>q; q.push(ST); while(!q.empty()) { int x = q.front(); q.pop(); for(int z = first[x]; z; z = nxt[z])if(cap[z]) { int y = w[z]; if(d[y] == -1) { d[y] = d[x] + 1; if(y == ED)return 1; q.push(y); } } } return 0; } int dfs(int x, int all) { if(x == ED)return all; int use = 0; for(int z = first[x]; z; z = nxt[z])if(cap[z]) { int y = w[z]; if(d[y] == d[x] + 1) { int tmp = dfs(y, min(cap[z], all - use)); cap[z] -= tmp; cap[z ^ 1] += tmp; use += tmp; if(use == all)break; } } if(use == 0)d[x] = -1; return use; } int dinic() { int tmp = 0; while(bfs())tmp += dfs(ST, inf); return tmp; } struct A { int x, y, o; }a[N]; struct B { int x, y, o,c; }b[N]; struct E{ int x,y,t; int sgn; E(){} E(int _x,int _y,int _t){ x=_x,y=_y,t=_t; if(!x)sgn=y>0; else sgn=x>0; } }e[400010]; inline bool cmpe(const E&a,const E&b){ if(a.sgn!=b.sgn)return a.sgn<b.sgn; int t=a.x*b.y-a.y*b.x; if(t)return t<0; return a.t<b.t; } int pre[400010],suf[400010]; int gcd(int a,int b){return b?gcd(b,a%b):a;} inline bool point_on_line(const A&a,const B&b){ int d1=gcd(abs(a.x),abs(a.y)),d2=gcd(abs(b.x),abs(b.y)); return (a.x/d1==b.x/d2)&&(a.y/d1==b.y/d2); } struct Point{ ll x,y; Point(){} Point(ll _x,ll _y){x=_x,y=_y;} }; inline ll cross(const Point&a,const Point&b){return a.x*b.y-a.y*b.x;} inline ll sig(ll x){ if(x==0)return 0; return x>0?1:-1; } typedef long double ld; const ld epsss=1e-10; struct Pointd{ ld x,y; Pointd(){} Pointd(ld _x,ld _y){x=_x,y=_y;} }; inline ld crossd(const Pointd&a,const Pointd&b){return a.x*b.y-a.y*b.x;} inline ll sigd(ld x){ if(fabs(x)<epsss)return 0; return x>0?1:-1; } inline int distance_cmp(const A&_a,const B&_b,const B&_c){ Point a(_a.x,_a.y); Point b(_b.x,_b.y); Point c(_c.x,_c.y); Point d; if(!cross(b,c)){ d=Point(-b.y,b.x); if(!cross(a,d))return 0; if(sig(cross(d,a))==sig(cross(d,b)))return -1; return 1; } ld L=sqrt(b.x*b.x+b.y*b.y); ld R=sqrt(c.x*c.x+c.y*c.y); Pointd aa(a.x,a.y); Pointd bb(b.x,b.y); Pointd cc(c.x,c.y); Pointd dd(d.x,d.y); bb.x*=R; bb.y*=R; cc.x*=L; cc.y*=L; dd=Pointd(bb.x+cc.x,bb.y+cc.y); if(!sigd(crossd(aa,dd)))return 0; if(sigd(crossd(dd,aa))==sigd(crossd(dd,bb)))return -1; return 1; } int main() { while(~scanf("%d%d",&n, &m)) { ST = 0; ED = n + m + 1; ID = 1; MS(first, 0); for(int i = 1; i <= n; ++i) { scanf("%d%d", &a[i].x, &a[i].y); a[i].o = i; } //sort a? for(int i = 1; i <= m; ++i) { scanf("%d%d%d", &b[i].x, &b[i].y,&b[i].c); b[i].o = i; } //sort b? int ce=0; for(int i=1;i<=n;i++){ e[++ce]=E(a[i].x,a[i].y,i); } for(int i=1;i<=m;i++){ e[++ce]=E(b[i].x,b[i].y,-i); } sort(e+1,e+ce+1,cmpe); pre[0]=0; for(int i=1;i<=ce;i++)if(e[i].t<0)pre[0]=-e[i].t; for(int i=1;i<=ce;i++){ pre[i]=pre[i-1]; if(e[i].t<0)pre[i]=-e[i].t; } suf[ce+1]=0; for(int i=ce;i;i--)if(e[i].t<0)suf[ce+1]=-e[i].t; for(int i=ce;i;i--){ suf[i]=suf[i+1]; if(e[i].t<0)suf[i]=-e[i].t; } for(int i=1;i<=ce;i++)if(e[i].t>0){ int x=e[i].t; int L=pre[i],R=suf[i]; if(L==R){ ins(x,L+n,1); continue; } if(point_on_line(a[x],b[L])){ ins(x,L+n,1); continue; } if(point_on_line(a[x],b[R])){ ins(x,R+n,1); continue; } int t=distance_cmp(a[x],b[L],b[R]); if(t<=0)ins(x,L+n,1); if(t>=0)ins(x,R+n,1); } for(int i = 1; i <= n; ++i) { ins(ST, i, 1); } for(int i = 1; i <= m; ++i) { ins(n + i, ED, b[i].c); } //addedge: &&maybe use a little greedy method printf("%d\n",dinic()); for(int i = 1; i <= n; ++i) { for(int z = first[i]; z; z = nxt[z]) { int y = w[z]; if(y > n && cap[z] == 0) { printf("%d %d\n", i - 1, y - n - 1); } } } } return 0; } /* 【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */
I. Import Spaghetti
枚举起点,BFS求最小环。
#include<cstdio> #include<map> #include<cstring> #include<iostream> #include<sstream> using namespace std; const int N=555; int n,i; string name[N]; bool g[N][N]; map<string,int>id; int ans=N,finS,finT; int d[N],f[N],q[N],h,t; inline int ask(string t){ string x=""; for(int i=0;i<t.size();i++)if(t[i]>='a'&&t[i]<='z')x.push_back(t[i]); return id[x]; } inline void ext(int x,int y,int z){ if(d[x]<0){ q[++t]=x; d[x]=y; f[x]=z; } } void bfs(int S){ int i,j,x; for(i=1;i<=n;i++)d[i]=-1; h=1,t=0; ext(S,0,0); while(h<=t){ x=q[h++]; int y=d[x]+1; for(i=1;i<=n;i++)if(g[x][i])ext(i,y,x); } for(i=1;i<=n;i++)if(d[i]>0&&g[i][S]){ int now=d[i]+1; if(now<ans)ans=now,finS=S,finT=i; } } int main(){ scanf("%d",&n); for(i=1;i<=n;i++){ cin>>name[i]; id[name[i]]=i; } for(i=1;i<=n;i++){ string tmp;int k; cin>>tmp>>k; char ss[2]; gets(ss); while(k--) { string s; getline(cin, s); stringstream cinn(s); int flag=1; while(cinn>>s) { if(flag){flag=0;continue;} int y=ask(s); g[y][i]=1; //printf("%d %d\n",i,y); } } } for(i=1;i<=n;i++)if(g[i][i]){ cout<<name[i]<<endl; return 0; } for(i=1;i<=n;i++)bfs(i); if(ans>=N){ puts("SHIP IT"); return 0; } //printf("%d %d %d\n",ans,finS,finT); bfs(finS); i=finT; while(i){ cout<<name[i]<<" "; i=f[i]; } } /* 4 a b c d a 1 import d, b, c b 2 import d import c c 1 import c d 0 5 classa classb myfilec execd libe classa 2 import classb import myfilec, libe classb 1 import execd myfilec 1 import libe execd 1 import libe libe 0 5 classa classb myfilec execd libe classa 2 import classb import myfilec, libe classb 1 import execd myfilec 1 import libe execd 1 import libe, classa libe 0 */
J. Judging Moose
按题意模拟即可。
#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math.h> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre() { } #define MS(x, y) memset(x, y, sizeof(x)) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; } template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; } const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f; template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; } int casenum, casei; int l, r; int main() { while(~scanf("%d%d",&l, &r)) { if(l + r == 0) { puts("Not a moose"); } else if(l == r) { printf("Even %d\n", l + r); } else { printf("Odd %d\n", max(l, r) * 2); } } return 0; } /* 【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */
K. Kayaking Trip
二分答案,贪心配对检验。
#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math.h> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre() { } #define MS(x, y) memset(x, y, sizeof(x)) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; } template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; } const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f; template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; } int casenum, casei; int n, m; int g[3], gg[3]; int s[3]; int c[N]; bool check(int aim) { gg[0] = g[0]; gg[1] = g[1]; gg[2] = g[2]; for(int i = 1; i <= m; ++i) { int need = aim / c[i] + (aim % c[i] > 0); int jj = -1; int kk = -1; for(int j = 0; j < 3; ++j) { for(int k = j; k < 3; ++k) { int num = 1; if(j == k)num = 2; if(gg[j] >= num && gg[k] >= num && s[j] + s[k] >= need) { if(jj == -1 || s[j] + s[k] < s[jj] + s[kk]) { jj = j; kk = k; } } } } if(jj == -1)return 0; gg[jj] -= 1; gg[kk] -= 1; // //printf("after ope %d: %d %d %d\n", i, gg[0], gg[1], gg[2]); // } return 1; } int main() { while(~scanf("%d%d%d",&g[0], &g[1], &g[2])) { scanf("%d%d%d",&s[0], &s[1], &s[2]); m = (g[0] + g[1] + g[2]) / 2; for(int i = 1; i <= m; ++i)scanf("%d", &c[i]); sort(c + 1, c + m + 1); int l = c[1] * (s[0] + s[0]); int r = c[m] * (s[2] + s[2]); // //l = r = 505; //printf("l == %d r == %d\n", l, r); // int ans = -1; while(l <= r) { int mid = (l + r + 1) / 2; if(check(mid)) { ans = mid; l = mid + 1; } else { r = mid - 1; } } printf("%d\n", ans); } return 0; } /* 【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */