• # 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
",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
", ans);
for(int i = 1; i <= 4; i ++){
//printf("%s
", 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
", 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
", 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]);}
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];
}
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
", 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
",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
", 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;
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;}
g[y][i]=1;
//printf("%d %d
",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
",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
", l + r);
}
else
{
printf("Odd %d
", 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
", 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
", 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
", ans);
}
return 0;
}

/*
【trick&&吐槽】

【题意】

【分析】

【时间复杂度&&优化】

*/
```

• 相关阅读:
ios正在使用NSDateComponents、NSDate、NSCalendar它的结论是在当前时间是在一段时间在一天。
linux 核心学习书籍
Hbase在的应用经验的统计
09-使用for循环输出空心菱形（循环）
[置顶] Android下实现自动关机的方法总结
S3C3440看门狗驱动程序
MySQL里求给定的时间是所在月份的第几个礼拜
CheckBox in ListView
根据复选框后面的描述文字进行选择的技巧
C#中一些易混知识的比较
• 原文地址：https://www.cnblogs.com/clrs97/p/7923485.html