题解 P7510 【铃解缀】
VinstaG173 · · 题解
小学数学经典题。小学曾在多个 MO 课听过做法。可是赛时由于设备原因写代码太麻烦了不想写,否则应该可以首 A(
首先,我们发现
上式左边是
然后感觉这个问题不是很好处理,联想到有解条件是
把
1 至n 各两个排成一列,使两个i 之间隔i 个数。
当时脑抽以为这个问题有解条件也是
但是发现如果把
回忆了一下以前讲的构造,记得我特别喜欢它的原因是除了几个数外都是两个
然后发现我的构造和 std 一模一样。。。大概就是这题引申过来的吧(
Code:
#include<cstdio>
#define rg register
int n;
int ans[2][1000003];
int main()
{
scanf(" %d",&n);
if(n&2)return 0&puts("-1 0");
int m=n>>2;
if(n&1)
{
ans[0][1]=1,ans[1][1]=2;
ans[0][n]=n,ans[1][n]=n<<1;
ans[0][n-2]=m+2,ans[1][n-2]=n+m;
ans[0][n>>1]=n+(n>>1),ans[1][n>>1]=m<<3|1;
ans[0][n-1]=(m+1)<<1,ans[1][n-1]=n+(m<<1|1);
for(rg int i=1;i<m;++i)
{
ans[0][n-((i+1)<<1)]=2+i,ans[1][n-((i+1)<<1)]=n-i;
ans[0][i<<1]=((m+1)<<1)-i,ans[1][i<<1]=((m+1)<<1)+i;
ans[0][n-(i<<1|1)]=n+i,ans[1][n-(i<<1|1)]=(m<<3|1)-i;
ans[0][i<<1|1]=n+(m<<1)-i,ans[1][i<<1|1]=n+(m<<1|1)+i;
}
}
else
{
ans[0][1]=1,ans[1][1]=2;
ans[0][n-1]=m+2,ans[1][n-1]=n+m+1;
ans[0][n>>1]=n|1,ans[1][n>>1]=n+(m<<1|1);
ans[0][n]=(m+1)<<1,ans[1][n]=n+((m+1)<<1);
for(rg int i=1;i<m;++i)
{
ans[0][n-(i<<1|1)]=2+i,ans[1][n-(i<<1|1)]=n-i+1;
ans[0][n-(i<<1)]=n+i+1,ans[1][n-(i<<1)]=(n<<1|1)-i;
ans[0][i<<1]=((m+1)<<1)-i,ans[1][i<<1]=((m+1)<<1)+i;
ans[0][i<<1|1]=n+(m<<1|1)-i,ans[1][i<<1|1]=n+((m+1)<<1)+i;
}
}
for(rg int i=1;i<=n;++i)printf("%d %d\n",ans[1][i],ans[0][i]);
return 0;
}