打卡信奥刷题(875)用C++信奥P11200[普及组/提高] [JOIG 2024] 座席 2 / Seats 2
P11200 [JOIG 2024] 座席 2 / Seats 2
题目描述
今年,JOI 国将主办 IOI(国际信息学奥林匹克竞赛)。届时将有 NNN 名选手参赛,编号从 111 到 NNN。
每位选手的国籍由一个介于 111 和 10910^9109 之间的整数表示:选手 i(1≤i≤N)i(1\le i\le N)i(1≤i≤N) 来自国家 CiC_iCi。保证 NNN 个选手的国籍不完全相同(即存在 i≠j(1≤i,j≤N)i\ne j(1\le i,j\le N)i=j(1≤i,j≤N) 使得 Ci≠CjC_i\ne C_jCi=Cj)。
选手的座位排成一条直线,选手 i(1≤i≤N)i(1\le i\le N)i(1≤i≤N) 的座位在 XiX_iXi 处。选手 i(1≤i≤N)i(1\le i\le N)i(1≤i≤N) 和选手 j(1≤j≤N)j(1\le j\le N)j(1≤j≤N) 之间的座位距离为 ∣Xi−Xj∣|X_i-X_j|∣Xi−Xj∣。
每个选手都想知道在与其他选手交流时,与离自己最近的异国选手的座位距离。
给定每个选手的国籍和座位位置,请为每个选手 i(1≤i≤N)i(1\le i\le N)i(1≤i≤N) 求出与其来自不同国家的选手中,座位离选手 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^52≤N≤3×105;
- 1≤Ci≤109(1≤i≤N)1\le C_i\le 10^9(1\le i\le N)1≤Ci≤109(1≤i≤N) 且 CiC_iCi 不完全相同;
- 1≤Xi≤109(1≤i≤N)1\le X_i\le 10^9(1\le i\le N)1≤Xi≤109(1≤i≤N)。
【子任务】
- (202020 分)N≤1000N\le 1000N≤1000;
- (404040 分)Ci≤10(1≤i≤N)C_i\le 10(1\le i\le N)Ci≤10(1≤i≤N);
- (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考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
更多推荐



所有评论(0)