CF R 635 div2 1337D Xenia and Colorful Gems 贪心 二分 双指针

LINK:Xenia and Colorful Gems

考试的时候没想到一个很好的做法。

赛后也有一个想法。

可以考虑答案的样子 x,y,z 可以发现 一共有 x<=y<=z,z<=y<=z,y<=x<=z...

6种情况 考虑 y<=x<=z 观察这个形式 枚举x 发现y在<=x中显然取较大的那个更优 证明的话 x不变 在z不变的情况 y在符合条件的情况下自然 越小越不优 再讨论z越大的问题 再讨论y z一个变小一个变大的情况 综上可以发现 y z都是要满足条件的第一个数时最优。

考虑暴力枚举6种情况然后计算。

但是 对于x<=y<=z的情况 可以发现枚举x 此时上述条件不成立了 对于找到的z来说 y在x和z中间 这样y就可以不满足我们上面说的条件了 可以夹在x和z中间。

怎么解决?非常巧妙的一点是 对于这种情况 我们枚举y 然后就重新满足上述条件了。

我这破脑子 就是想不到啊.值得注意的是找前驱和后继 可以指针直接扫 觉得麻烦可以直接lower bound和upper bound.

const ll MAXN=100010;
ll T;
ll na,nb,nc,ans;
vector<int>g[3];
inline ll js(ll a,ll b,ll c){return pf(a-b)+pf(a-c)+pf(b-c);}
inline void solve(int a,int b,int c)//a<=b<=c;
{
	for(ui i=0;i<g[b].size();++i)
	{
		ll y,z;y=upper_bound(g[a].begin(),g[a].end(),g[b][i])-g[a].begin()-1;
		if(y!=-1)
		{
			z=lower_bound(g[c].begin(),g[c].end(),g[b][i])-g[c].begin();
			if(z!=g[c].size())ans=min(ans,js(g[b][i],g[c][z],g[a][y]));
		}
	}
}
signed main()
{
	freopen("1.in","r",stdin);
	get(T);
	while(T--)
	{
		g[0].clear();g[1].clear();
		g[2].clear();
		get(na);get(nb);get(nc);
		rep(1,na,i)g[0].pb(read());
		rep(1,nb,i)g[1].pb(read());
		rep(1,nc,i)g[2].pb(read());
		sort(g[0].begin(),g[0].end());
		sort(g[1].begin(),g[1].end());
		sort(g[2].begin(),g[2].end());
		ans=INF;
		//cout<<lower_bound(g[0].begin(),g[0].end(),10)-g[0].begin();
		solve(1,0,2);solve(2,0,1);
		solve(0,1,2);solve(2,1,0);
		solve(0,2,1);solve(1,2,0);
		putl(ans);
	}
	return 0;
}
posted @ 2020-04-16 19:02  chdy  阅读(116)  评论(0编辑  收藏  举报