Codeforces Round #635 (Div. 2) 比赛人数14830
[codeforces 1337D] Xenia and Colorful Gems 寻找6种组合
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1337/problem/D
| Problem | Lang | Verdict | Time | Memory |
|---|---|---|---|---|
| D - Xenia and Colorful Gems | GNU C++17 | Accepted | 140 ms | 9400 KB |
思路如下:
共有6种颜色组合(rgb,bgr,grb,brg,rbg,gbr)
将3种颜色的数组组成新的数组,
按数值自小到大排序,
对新的数组进行遍历,
会遇到三种颜色r,g,b
若遇到颜色r,会遇到两种组合,grb,brg,注意,让遇到的这个位置的颜色r,充当中间位置的颜色。
如grb,可找到离该位置最近的左侧g颜色的值,可找到离该位置最近的右侧b颜色的值,与当前的r颜色的值,作运算,
找最小值。
若遇到颜色g,思路如上。
若遇到颜色b,思路如上。
若觉得文字理解不了,请看如下模拟
2 2 3
7 8
6 3
3 1 4
14
位置 1 2 3 4 5 6 7
数值(颜色)1(b) 3(b) 3(g) 4(b) 6(g) 7(r) 8(r)
读到位置1(对应颜色b):左边找不到其它颜色,此组数据无效
读到位置2(对应颜色b):左边找不到其它颜色,此组数据无效
读到位置3(对应颜色g):
左边找到最近的b颜色(位置2),右边找到最近的r颜色(位置6),该组颜色组合bgr,对应位置(2,3,6)
值(3-3)^2+(3-7)^2+(3-7)^2=32
读到位置4(对应颜色b):
左边找到最近的g颜色(位置3),右边找到最近的r颜色(位置6),该组颜色组合gbr,对应位置(3,4,6)
值(3-4)^2+(3-7)^2+(4-7)^2=26
读到位置5(对应颜色g):
左边找到最近的b颜色(位置4),右边找到最近的r颜色(位置6),该组颜色组合bgr,对应位置(4,5,6)
值(4-6)^2+(4-7)^2+(6-7)^2=14
读到位置6(对应颜色r):右边找不到其它颜色,此组数据无效
读到位置7(对应颜色r):右边找不到其它颜色,此组数据无效
在上述值中,取最小值14
AC代码如下
#include <cstdio>
#include <algorithm>
#define LL long long
#define maxn 100010
using namespace std;
struct node{
int color,v;//color r:0,g:1,b:2;
}q[maxn*3];
LL ans;
int left[3][maxn*3],right[3][maxn*3],n;//right[i][j]=k代表j位置(包括该位置)右侧,颜色i最靠近的位置是k
int cmp(node a,node b){
return a.v<b.v;
}
LL f(LL x,LL y,LL z){//x,y,z对应球的数值
return (x-y)*(x-y)+(y-z)*(y-z)+(z-x)*(z-x);
}
void solve(int x,int y,int z,int pos){//x,y,z对应三种颜色,pos对应中间颜色y在新数组中的位置
int lp,rp;//lp左侧位置,rp右侧位置
lp=left[x][pos],rp=right[z][pos];//lp确定左边离pos最近的x颜色的位置
if(lp==0)return;//左边找不到其它颜色
if(rp==n+1)return;//rp确定右边离pos最近的z颜色的位置
ans=min(ans,f(q[lp].v,q[pos].v,q[rp].v));
}
int main(){
int t,nr,ng,nb,i,j,color,x,y,z;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&nr,&ng,&nb);
ans=5e18,n=nr+ng+nb;
for(i=1;i<=nr;i++)scanf("%d",&q[i].v),q[i].color=0;
for(;i<=nr+ng;i++)scanf("%d",&q[i].v),q[i].color=1;
for(;i<=nr+ng+nb;i++)scanf("%d",&q[i].v),q[i].color=2;
sort(q+1,q+1+n,cmp);//按值自小到大排序
for(i=0;i<3;i++)right[i][n+1]=n+1;//初始化到边界外,表明找不到
for(i=n;i>=1;i--){
for(j=0;j<3;j++)right[j][i]=right[j][i+1];
color=q[i].color,right[color][i]=i;
}
for(i=0;i<3;i++)left[i][0]=0;//left[i][j]=k代表j位置(包括该位置)左侧,颜色i最靠近的位置是k
for(i=1;i<=n;i++){
for(j=0;j<3;j++)left[j][i]=left[j][i-1];
color=q[i].color,left[color][i]=i;
}
for(i=1;i<=n;i++){
y=q[i].color,x=(y+1)%3,z=3-(x+y);//确定三种颜色
solve(x,y,z,i),solve(z,y,x,i);
}
printf("%lld\n",ans);
}
return 0;
}
该题,与最近几天比赛的题目极其类似,感谢兴趣的可以看一看
AtCoder Beginner Contest 162 D RGB Triplets 前缀和
[codeforces 1335E1] Three Blocks Palindrome (easy version) 分成左中右3个区间+前缀和
[codeforces 1335E2] Three Blocks Palindrome (hard version) 从中间位置向两边扩散
本文详细解析了Codeforces Round #635 (Div.2) 中 D 题 Xenia and Colorful Gems 的解题思路与算法实现。介绍了如何通过组合不同颜色宝石的位置来找出所有可能的六种颜色组合,并使用前缀和的方法来优化搜索过程,最终求得最小代价。

294

被折叠的 条评论
为什么被折叠?



