题解:P12176 [蓝桥杯 2025 省 Python B] 书架还原
wenqinghua1001 · · 题解
思路
我一看到这道题,认为是再求逆序对的个数,打了一个代码。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1000010;
int ans=0;
int a[N],b[N],n;
void work(int l,int mid,int r){
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r){
if(a[i]<=a[j])
b[++k]=a[i++];
else{
b[++k]=a[j++];
ans+=mid-i+1;
}
}
while(i<=mid)
b[++k]=a[i++];
while(j<=r)
b[++k]=a[j++];
for(int i=l;i<=r;i++)
a[i]=b[i-l+1];
}
void msort(int l,int r){
if(l>=r) return ;
int mid=(l+r)/2;
msort(l,mid);
msort(mid+1,r);
work(l,mid,r);
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
msort(1,n);
cout<<ans;
return 0;
}
逝世的测试信息。
我的天哪!我仔细理了一下题目,发现不是在求逆序对。
这道题要求书架上的书恢复到正确排列所需的最少操作次数,那么肯定要最优解,数据范围是
首先,第
对重要结论的证明:我们发现这道题中不该在相应位置的位置,刚好形成了一个环,而且恰好每个环使用了
代码
C++ 代码
AC 记录
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[10000001];
int b[10000001];
signed main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
b[a[i]]=i;
int ans=0;
for(int i=1;i<=n;i++){
if(a[i]!=i){
// 不符合条件。
b[a[i]]=b[i];
swap(a[i],a[b[i]]);
// 把不符合条件的两个数位置交换。
// 保证最优。
ans++;
}
}
cout<<ans;
return 0;
}
Python 代码
AC 记录
n=int(input())
nums=list(map(int,input().split()))
ans=0
for i in range(n):
while nums[i]!=i+1 :
# 不符合条件。
j=nums[i]-1
tmp=nums[j]
nums[j]=nums[i]
nums[i]=tmp
# 把不符合条件的两个数位置交换。
# 保证最优。
ans+=1
print(ans)