题解:P6892 [ICPC 2014 WF] Baggage
xzy_AK_IOI · · 题解
一种与题解不同的做法。
思路分析
观察样例,发现一些性质,比较好看出最小操作数为
通过手模样例,发现第二个
这是前四步的操作,具体地,我们可以发现它将前面
但这并不适用于所有区间,可以发现,这只适用于
n\equiv 0\pmod {4}
以上已讨论过第一部分,即只交换
下面再看
可以看出这是前
n\equiv 1\pmod {4}
观察
发现换到这一步时不满足第一种情况的规律,具体的,中间的
发现其实是将前
然后依然是和上面一样的,较简单,不再叙述。
n\equiv 3\pmod {4}
手模
打表发现其中一种解是这样的:
依照上述方法,将其化为长度为
对于第
n\equiv 2\pmod {4}
直接手摸
发现可以将它化为前后各
记得特判
完整代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lli long long
#define db long double
#define ull unsigned long long
#define F(i,k,n) for (int i=k;i<=n;i++)
#define R(i,k,n) for (int i=k;i>=n;i--)
#define pu push_back
#define mpr make_pair
#define ins insert
#define lowb(x) (x&(-x))
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define mes(a,b) memset(a,b,sizeof a)
const int N=1e5+10;
const int M=50;
const int inf=1e12;
int n;
int a[N],b[N];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n;
if (n%4==0){
a[1]=-1;
b[1]=2;
F(i,2,n/4){
a[i]=a[i-1]+4;
b[i]=b[i-1]+4;
}
a[n/2]=2*n-3;
b[n/2]=2*n;
R(i,n/2-1,n/4+1){
a[i]=a[i+1]-4;
b[i]=b[i+1]-4;
}
F(i,n/4+1,n/2-1){
cout<<a[i]+1<<" to "<<a[i-n/4]<<'\n';
cout<<a[i+1-n/4]<<" to "<<a[i]+1<<'\n';
}
cout<<a[n/2]+1<<" to "<<a[n/4]<<'\n';
cout<<b[n/4]+1<<" to "<<a[n/2]+1<<'\n';
cout<<a[1]+1<<" to "<<b[n/4]+1<<'\n';
cout<<a[n/4+1]+2<<" to "<<a[1]+1<<'\n';
F(i,2,n/4){
cout<<a[i]+1<<" to "<<a[i+n/4-1]+2<<'\n';
cout<<a[i+n/4]+2<<" to "<<a[i]+1<<'\n';
}
}
else if (n%4==1){
a[1]=-1;
b[1]=2;
F(i,2,(n+1)/2){
a[i]=a[i-1]+4;
b[i]=b[i-1]+4;
}
F(i,1,n/4){
cout<<a[(n+1)/2-i+1]+1<<" to "<<a[i]<<'\n';
cout<<a[i+1]<<" to "<<a[(n+1)/2-i+1]+1<<'\n';
}
cout<<b[n/4+1]<<" to "<<a[n/4+1]<<'\n';
cout<<a[1]+1<<" to "<<b[n/4+1]<<'\n';
F(i,1,n/4-1){
cout<<a[i+n/4+1]+2<<" to "<<a[i]+1<<'\n';
cout<<a[i+1]+1<<" to "<<a[i+n/4+1]+2<<'\n';
}
cout<<a[(n+1)/2]+2<<" to "<<a[n/4]+1<<'\n';
}
else if (n%4==3){
if (n==3){
cout<<"2 to -1\n5 to 2\n3 to -3";
return 0;
}
a[1]=-1;
b[1]=2;
F(i,2,(n+1)/2){
a[i]=a[i-1]+4;
b[i]=b[i-1]+4;
}
F(i,1,n/4-1){
cout<<a[(n+1)/2-i+1]+1<<" to "<<a[i]<<'\n';
cout<<a[i+1]<<" to "<<a[(n+1)/2-i+1]+1<<'\n';
}
cout<<a[(n+1)/2-n/4+1]+1<<" to "<<a[n/4]<<'\n';
cout<<a[n/4+1]+2<<" to "<<a[(n+1)/2-n/4+1]+1<<'\n';
cout<<a[n/4+2]+1<<" to "<<a[n/4+1]+2<<'\n';
cout<<a[n/4+1]<<" to "<<a[n/4+2]+1<<'\n';
cout<<a[n/4+2]+2<<" to "<<a[n/4+1]<<'\n';
F(i,n/4+2,(n+1)/2-1){
cout<<a[(n+1)/2-i]+1<<" to "<<a[i]+2<<'\n';
cout<<a[i+1]+2<<" to "<<a[(n+1)/2-i]+1<<'\n';
}
}
else{
a[1]=-1;
b[1]=2;
F(i,2,n/4){
a[i]=a[i-1]+4;
b[i]=b[i-1]+4;
}
a[n/2]=2*n-3;
b[n/2]=2*n;
R(i,n/2-1,n/4+1){
a[i]=a[i+1]-4;
b[i]=b[i+1]-4;
}
F(i,1,n/4-1){
cout<<a[n/2-i+1]+1<<" to "<<a[i]<<'\n';
cout<<a[i+1]<<" to "<<a[n/2-i+1]+1<<'\n';
}
cout<<a[n/4+2]+1<<" to "<<a[n/4]<<'\n';
cout<<a[n/4+1]+2<<" to "<<a[n/4+2]+1<<'\n';
cout<<b[n/4]<<" to "<<a[n/4+1]+2<<'\n';
cout<<a[n/4+1]+1<<" to "<<b[n/4]<<'\n';
cout<<a[n/4]+1<<" to "<<a[n/4+1]+1<<'\n';
cout<<a[n/4+2]+2<<" to "<<a[n/4]+1<<'\n';
R(i,n/4-1,1){
cout<<a[i]+1<<" to "<<a[n/2-i]+2<<'\n';
cout<<a[n/2-i+1]+2<<" to "<<a[i]+1<<'\n';
}
}
return 0;
}