#include<stdio.h>
#include<string.h>
#include<map>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;
#define MS(x,y) memset(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
const int dy[2][4]={0,1,0,1, 1,0,-1,0};
const int dx[2][4]={1,0,-1,0, 0,1,0,1};
int n,H,W;
const int N=1005;
vector<pair<int,int> >a[N];
int b[N][N];
void push(int w,int y,int x)
{
a[w].push_back(MP(y,x));
b[y][x]=w;
}
void listfill(int y,int x,int w1,int w2)
{
int size1=w1;
int size2=w2;
int d=0;
while(size1--)
{
push(w1,y,x);
y+=dy[0][d];
x+=dx[0][d];
d=(d+1)%4;
}
while(size2--)
{
push(w2,y,x);
y+=dy[0][d];
x+=dx[0][d];
d=(d+1)%4;
}
}
void linefill(int y,int x,int w1,int w2)
{
int size1=w1;
int size2=w2;
int d=0;
while(size1--)
{
push(w1,y,x);
y+=dy[1][d];
x+=dx[1][d];
d=(d+1)%4;
}
while(size2--)
{
push(w2,y,x);
y+=dy[1][d];
x+=dx[1][d];
d=(d+1)%4;
}
}
//用所以奇数画正方形
void square(int y,int x,int top)
{
for(int o=top;o>=1;o-=2)
{
++y;
++x;
int d=o/2;
int yy=y+d;
int xx=x+d;
for(int i=yy;i>=y;i--)push(o,i,x);
for(int i=x+1;i<=xx;i++)push(o,y,i);
}
}
//用所有偶数画矩形
void rectangle(int h,int w,int top)
{
if(h&1)
{
int u=top;
int v=h+h-u;
int x=1;
while(u>v)
{
listfill(1,x,u,v);
u-=2;
v+=2;
x+=2;
}
}
else
{
int u=top;
int v=w+w-u;
int y=1;
while(u>v)
{
linefill(y,1,u,v);
u-=2;
v+=2;
y+=2;
}
}
}
void odd()
{
H=(n+1)/2;
W=n;
int mv=n;
int h=H;
int w=W-(mv+1)/2;
square(0,w,mv);
rectangle(h,w,n-1);
}
void even()
{
H=n/2;
W=n+1;
int mv=n-1;
int h=H;
int w=W-(mv+1)/2;
square(0,w,mv);
rectangle(h,w,n);
}
void printmap()
{
for(int i=1;i<=H;i++)
{
for(int j=1;j<=W;j++)printf("%d ",b[i][j]);
puts("");
}
}
void print()
{
printf("%d %d\n",H,W);
for(int i=1;i<=n;i++)
{
for(int j=0;j<i;j++)printf("%d %d ",a[i][j].first,a[i][j].second);
puts("");
}
//printmap();
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)a[i].clear();
if(n&1)odd();
else even();
print();
}
return 0;
}
/*
【trick&&吐槽】
比赛的时候不要太悠闲了,不给自己的压力很多时候造成的恶果是,悲惨地只恰好差一分钟AC TwT
【题意】
给你一个n([1,500]),表示有n条蛇,蛇的身长从1到n,每条蛇所占的格子数也恰好等于其身长。
我们希望把这n条蛇,不交叉不溢出地都放到一个h*w的矩形中。(也就是说h*w=(1+n)*n/2)
并且使得:
对于身长为奇数的蛇(1除外),其扭曲的次数恰好为奇数;
对于身长为偶数的蛇(2除外),其扭曲的次数恰好为偶数。
让你构造出其方案,并按照身长从1~n,依次输出所有蛇。对于每条蛇,从头到尾输出其u偶在位置。
【类型】
构造
【分析】
首先,我们要分析这个矩形的形状,矩形的形状是h*w的话,h和w必定是其面积和的因子。
于是我每次想要枚举出最小的满足这个要求的h,然后再进行构造,然后就踏上了悲惨之路。
一个比较优秀的姿势是什么呢?
就是——既然h*w=(1+n)*n/2,我们就从这个公式入手!
所以,如果n为奇数,那我们就有因子{(1+n)/2和n};
如果n为偶数,那我们就有因子{n/2和(1+n)}。
然后,我们观察到,不论n为奇数还是偶数,对于所有的奇数,我们都是可以这么安排的——
1357
3357
5557
7777
我们发现,当n为奇数时,所有的奇数,恰好可以构成一个(n+1)/2的正方形
当n为偶数时,所有的奇数,恰好可以构成一个(n-1+1)/2=n/2的正方形
于是,我们可以剔除这个正方形。
然后,对于n为奇数,目前的矩形就是(n+1)/2 * (n-1)/2
对于n为偶数,目前的矩形就是n/2 * (n+2)/2
然后我们此时剩下的全部都是偶数
对于n%4==1,(n+1)/2 * (n-1)/2 可以用(n-1,2),(n-3,4)这样凑,形成的对数恰好是(n-1)/4对,每对的和恰好是n+1
对于n%4==2,n/2 * (n+2)/2 可以用(n)(n-2,2),(n-4,4)这样凑,形成的对数恰好是(n+2)/4对,每对的和恰好是n
对于n%4==3,(n+1)/2 * (n-1)/2 可以用(n-1)(n-3,2),(n-5,4)这样凑,形成的对数恰好是(n+1)/4对,每对的和恰好是n-1
对于n%4==0,n/2 * (n+2)/2 可以用(n,2)(n-2,4),(n-4,6)这样凑,形成的对数恰好是n/4对,每对的和恰好是(n+2)
而()中的每个数或每一对,能拐就拐,于是就都很容易就在2*d的格子中构造出解。于是就可以AC啦。
这个可以分开写,也可以归纳写,总之我们就可以这样AC啦~啦啦啦啦~
【时间复杂度&&优化】
O((n+1)*n/2)
*/
【hihocoder1257 2015北京赛区I】【构造 从公式入手】Snake Carpet 构造矩阵使得恰好容纳1~n个拐拐蛇行图案
最新推荐文章于 2018-10-09 23:12:48 发布