Codeforces Global Round 3 C. Crazy Diamond
13776 ワード
リンク
https://codeforces.com/problemset/problem/1148/C
問題解
1 1 1とn n nの2つの位置が便利であることが容易に発見され、1 1 1は右半分のいずれかと交換することができ、n n nは左半分のいずれかと交換することができるので、私が構築した戦略は、左半分に交換したい数字について、まずn n nに交換させ、それから正しい位置に交換する方法を考えています.もしこの数字が今左半分にあるなら、私は直接n n nと交換させます.さもないと1 1 1と交換してからn nと交換することができます
コード#コード#
https://codeforces.com/problemset/problem/1148/C
問題解
1 1 1とn n nの2つの位置が便利であることが容易に発見され、1 1 1は右半分のいずれかと交換することができ、n n nは左半分のいずれかと交換することができるので、私が構築した戦略は、左半分に交換したい数字について、まずn n nに交換させ、それから正しい位置に交換する方法を考えています.もしこの数字が今左半分にあるなら、私は直接n n nと交換させます.さもないと1 1 1と交換してからn nと交換することができます
コード#コード#
#include
#define maxn 300010
#define linf (1ll<<60)
#define iinf 0x3f3f3f3f
#define eps 1e-8
#define cl(x) memset(x,0,sizeof(x))
#define mod 998244353ll
#define mp(a,b) make_pair(a,b)
using namespace std;
typedef long long ll;
ll read(ll x=0)
{
int c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
ll N, a[maxn], pos[maxn];
vector< pair<ll,ll> > ans;
void opt(ll x, ll y)
{
ans.emplace_back(make_pair(x,y));
swap(pos[a[x]],pos[a[y]]);
swap(a[x],a[y]);
}
int main()
{
N=read();
ll i;
for(i=1;i<=N;i++)
{
a[i]=read();
pos[a[i]]=i;
}
for(i=2;i<=N/2;i++)
{
if(pos[i]<=N/2)
{
opt(pos[i],N);
opt(N,i);
}
else
{
opt(pos[i],1);
opt(1,N);
opt(N,i);
}
}
for(;i<N;i++)
{
if(pos[i]<=N/2)
{
opt(pos[i],N);
opt(N,1);
opt(1,i);
}
else
{
opt(1,pos[i]);
opt(1,i);
}
}
if(a[1]!=1)opt(1,N);
printf("%d
",ans.size());
for(auto p:ans)
{
printf("%lld %lld
",p.first,p.second);
}
return 0;
}