题意:
输出满足|p1−1|+|p2−2|+…+|pn−n|=k的数组p,数组p为1到n的全排列
分析:
每次遍历,寻找符合条件的可以交换的最大数字
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void sol(){
ll n,k;cin>>n>>k;ll ma=0;
for(int i=1;i<=n/2;i++){
ma+=2*(n-i+1-i);
}
if(k>ma||k%2!=0)cout<<"NO"<<endl;
else if(k==0){
cout<<"YES"<<endl;
for(int i=1;i<=n;i++)cout<<i<<" ";
cout<<endl;
}
else if(k==ma){
cout<<"YES"<<endl;
for(int i=n;i>=1;i--)cout<<i<<" ";
cout<<endl;
}
else{
ll ans=0;
ll l=1,r=n;
ll a[n+10];
for(int i=1;i<=n;i++)a[i]=i;
for(int i=1;i<=n;i++){
if(ans<k&&a[i]==i){
l=i,r=n;
while(l<r){
int mid=(l+r+1)/2;
if(2*abs(a[mid]-a[i])+ans>k||a[mid]!=mid)r=mid-1;
else l=mid;
}
if(l!=i){
ans+=2*(a[l]-a[i]);
swap(a[l],a[i]);
}
}
else break;
}
cout<<"YES"<<endl;
for(int i=1;i<=n;i++)
cout<<a[i]<< " ";
cout<<endl;
}
}
int main(){
int t;cin>>t;
while(t--)sol();
return 0;
}