代码源每日一题(补)社交圈
社交圈
又上网课了,离昆明场多了七天,现在还剩接近20天,抓紧补题了
题目
现在有 \(N\) 个人,每一个人都不想周围的人坐得离他很近,所以在他的左边要放$ L_i$ 张空椅子,右边要放 \(R_i\) 张空椅子,同时每个人自己要坐 \(1\) 张椅子。
现在他们要坐成若干个圈,请问最少要放多少张椅子(包括每个人自己坐的椅子)?
输入格式
第 11 行一个整数 \(N\)。
第 22 行至第\(N+1\) 行每行两个整数 \(L_i\) 和 \(R_i\)。
输出格式
一个整数,表示最少需要的椅子数量。
样例输入
4
1 2
2 1
3 5
5 3
样例输出
15
数据规模
\(1≤N≤1×10^5\)
\(0≤L_i,R_i≤1×10^9。\)
题目分析
对于第i个人来讲,其右边的距离为:
\[Ans[i]=max(left[i],right[i+1])
\]
也就是说,右边的距离要么是你右边的限制,要么是后一个人左边的限制,答案为
\[ans = \sum_{i=1}^n max(left[i],right[i+1])
\]
对于每一个点来讲,规划好其右边的距离即可,如果考虑成环的话,也不难,由于题目说明了若干个环,所以第一个人左边只要和最后一个人右边成最优解后,再对剩余的人分析,依旧不影响最终结果。
至此,问题化成了如何让左右最相似,对数组分别按左边顺序、右边顺序排序即可。
Accept code
//http://oj.daimayuan.top/course/10/problem/606
//2022-03-29 finish
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+7;
struct Node{
ll l,r;
int num;
}a[N],b[N];
bool vis[N];
bool cmp1(Node x,Node y) {
return x.l < y.l;
}
bool cmp2(Node x,Node y) {
return x.r < y.r;
}
int main() {
int n;
scanf("%d",&n);
for(int i = 1 ; i <= n ; i++) {
scanf("%lld%lld",&a[i].l,&a[i].r);
b[i].l = a[i].l, b[i].r = a[i].r;
b[i].num = a[i].num = i;
}
sort(a+1,a+n+1,cmp1);
sort(b+1,b+n+1,cmp2);
ll ans = n;
for(int i = 1 ; i <= n ; i++) {
ans += max(a[i].l,b[i].r);
}
cout << ans;
}

浙公网安备 33010602011771号