P11200 [JOIG 2024] 座席 2 / Seats 2

题目描述

今年,JOI 国将主办 IOI(国际信息学奥林匹克竞赛)。届时将有 NNN 名选手参赛,编号从 111NNN

每位选手的国籍由一个介于 11110910^9109 之间的整数表示:选手 i(1≤i≤N)i(1\le i\le N)i(1iN) 来自国家 CiC_iCi。保证 NNN 个选手的国籍不完全相同(即存在 i≠j(1≤i,j≤N)i\ne j(1\le i,j\le N)i=j(1i,jN) 使得 Ci≠CjC_i\ne C_jCi=Cj)。

选手的座位排成一条直线,选手 i(1≤i≤N)i(1\le i\le N)i(1iN) 的座位在 XiX_iXi 处。选手 i(1≤i≤N)i(1\le i\le N)i(1iN) 和选手 j(1≤j≤N)j(1\le j\le N)j(1jN) 之间的座位距离∣Xi−Xj∣|X_i-X_j|XiXj

每个选手都想知道在与其他选手交流时,与离自己最近的异国选手的座位距离。

给定每个选手的国籍和座位位置,请为每个选手 i(1≤i≤N)i(1\le i\le N)i(1iN) 求出与其来自不同国家的选手中,座位离选手 iii 最近的选手与 iii 的座位距离。

输入格式

第一行输入一个整数 NNN

接下来 NNN 行,每行输入两个整数 Ci,XiC_i,X_iCi,Xi

输出格式

输出 NNN 行,第 iii 行输出一个整数,表示座位离选手 iii 最近的选手与 iii 的座位距离。

输入输出样例 #1

输入 #1

3
2 5
1 1
1 2

输出 #1

3
4
3

输入输出样例 #2

输入 #2

5
1 1
2 4
2 14
3 10
2 2

输出 #2

1
3
4
4
1

输入输出样例 #3

输入 #3

3
1 1
2 1
1 1

输出 #3

0
0
0

说明/提示

【样例解释 #1】
  • 选手 111 来自国家 222,选手 2,32, 32,3 和他 / 她来自不同国家。在这些选手中,与选手 111 座位距离最小的是选手 333,座位距离为 333。因此,答案为 333
  • 选手 222 来自国家 111,选手 111 是唯一和他 / 她来自不同国家的选手。选手 222 和选手 111 之间的座位距离为 444
  • 选手 333 来自国家 111,选手 111 是唯一和他 / 她来自不同国家的选手。选手 333 和选手 111 之间的座位距离为 333

该样例满足子任务 1,2,31,2,31,2,3 的限制。

【样例解释 #2】

该样例满足子任务 1,2,31,2,31,2,3 的限制。

【样例解释 #3】

该样例满足子任务 1,2,31,2,31,2,3 的限制。

【数据范围】
  • 2≤N≤3×1052\le N \le 3\times 10^52N3×105
  • 1≤Ci≤109(1≤i≤N)1\le C_i\le 10^9(1\le i\le N)1Ci109(1iN)CiC_iCi 不完全相同;
  • 1≤Xi≤109(1≤i≤N)1\le X_i\le 10^9(1\le i\le N)1Xi109(1iN)
【子任务】
  1. 202020 分)N≤1000N\le 1000N1000
  2. 404040 分)Ci≤10(1≤i≤N)C_i\le 10(1\le i\le N)Ci10(1iN)
  3. 404040 分)无附加限制。

C++实现

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int n;
int dis[N];
struct Node{
int num,c,x;
}f[N];
bool cmp(Node a,Node b){
return a.x<b.x;
}
int main(){
memset(dis,0x3f,sizeof(dis));
cin>>n;
for(int i=1;i<=n;i++){
cin>>f[i].c>>f[i].x;
f[i].num=i;
}
sort(f+1,f+n+1,cmp);
for(int i=2;i<=n;i++){
if(f[i].c!=f[i-1].c){
dis[f[i].num]=min(dis[f[i].num],f[i].x-f[i-1].x);
}
else{
dis[f[i].num]=min(dis[f[i-1].num]+f[i].x-f[i-1].x,dis[f[i].num]);
}
}
for(int i=n-1;i>=1;i–){
if(f[i].c!=f[i+1].c){
dis[f[i].num]=min(dis[f[i].num],f[i+1].x-f[i].x);
}
else{
dis[f[i].num]=min(dis[f[i+1].num]+f[i+1].x-f[i].x,dis[f[i].num]);
}
}
for(int i=1;i<=n;i++){
cout<<dis[i]<<“\n”;
}
return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

Logo

2万人民币佣金等你来拿,中德社区发起者X.Lab,联合德国优秀企业对接开发项目,领取项目得佣金!!!

更多推荐