P5846题解
其实这道题比较水,果然是远古时期的题我们假设每一名同学都向一个方向移动,此时距离确定,我们发现,如果考虑两个方向,比如有
| 距离 | 方向 |
|---|---|
| 某个格子向左和向右均为此数,只有一个 | |
| 向右 | |
| 向左 | |
| 向右 | |
| 向左 | |
| 无 |
为
| 距离 | 方向 |
|---|---|
| 向右 | |
| 向左 | |
| 向右 | |
| 向左 | |
| 向右 | |
| 向左 | |
| 无 |
而当我们指定方向时,就有距离为
当
| 特定方向距离 | 实际距离 |
|---|---|
当
| 特定方向距离 | 实际距离 |
|---|---|
不难发现我们可以将座位号进行转圈,比如
#include<bits/stdc++.h>
using namespace std;
bool t[1000009];
int a[1000009];
int main(){
int n;
int ma;
int u;
int x,y;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
memset(t,0,sizeof(t));
for(int i=1;i<=n;i++){//特定方向距离记录
t[(a[i]-i+n)%n]=1;
}
ma=0;
u=0;
for(int i=0;i<n;i++){//算最长连续无同学对应座位
if(t[i]){
ma=max(ma,u);
u=0;
}else{
u++;
}
}
ma=max(ma,u);
u=0;
for(int i=0;i<n;i++){//特判循环
if(!t[i]){
u++;
}else{
break;
}
}
for(int i=n-1;i>=0;i--){
if(!t[i]){
u++;
}else{
break;
}
}
ma=max(ma,u);
x=n/2;
if(n%2){//分奇偶情况
x-=ma/2;
}else{
if(ma>0){
x--;
ma--;
}
x-=ma/2;
}
memset(t,0,sizeof(t));//倒过来算
for(int i=1;i<=n;i++){
t[(a[n+1-i]-i+n)%n]=1;
}
ma=0;
u=0;
for(int i=0;i<n;i++){
if(t[i]){
ma=max(ma,u);
u=0;
}else{
u++;
}
}
ma=max(ma,u);
u=0;
for(int i=0;i<n;i++){
if(!t[i]){
u++;
}else{
break;
}
}
for(int i=n-1;i>=0;i--){
if(!t[i]){
u++;
}else{
break;
}
}
ma=max(ma,u);
y=n/2;
if(n%2){
y-=ma/2;
}else{
if(ma>0){
y--;
ma--;
}
y-=ma/2;
}
cout<<min(x,y);
return 0;
}
不难发现这是贪心作者我写到几乎末尾才发现 思路的话我思路不是特别清晰,所以写的特别啰嗦,所以大家主要看代码,思路仅供参考,帮助大家理解,祝大家切题愉快。