//Lib #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<ctime> #include<iostream> #include<algorithm> #include<vector> #include<string> #include<queue> using namespace std; //Macro #define rep(i,a,b) for(int i=a;i<=b;++i) #define rrep(i,a,b) for(int i=a;i>=b;--i) #define erep(i,e,x) for(int i=x;i;i=e[i].next) #define irep(i,x) for(__typedef(x.begin()) i=x.begin();i!=x.end();i++) #define read() (strtol(ipos,&ipos,10)) #define sqr(x) ((x)*(x)) #define pb push_back #define PS system("pause"); typedef long long ll; typedef pair<int,int> pii; const int oo=~0U>>1; const double inf=1e20; const double eps=1e-6; string name="",in=".in",out=".out"; //Var int n,k; void Work() { scanf("%d",&n); if(n==2){printf("3 4\n5 2 3\n");return;} printf("%d",k=n); rep(i,2,n-1) rep(j,n-i+1,n-1) printf(" %d",i*n+j+1); printf("\n%d",k+=1+(n&1)); rep(j,0,n-2)printf(" %d",n*2+j*(n-1)); k+=2; for(int i=n;k<3*n+1;k+=2,i--) { printf("\n%d",k); rep(j,0,i-1)printf(" %d",i+j*(n-1)); } puts(""); } int main() { // freopen((name+in).c_str(),"r",stdin); // freopen((name+out).c_str(),"w",stdout); // Init(); Work(); return 0; }
题目大意:
一个人在nxn的棋盘上任意走(至少走n步至多299步),起点在左上角,每次走完以后,你可以去掉一些格子使得他不能走到那些格子
人如何走是不确定的,但走的步数和删去多少格子以及哪些格子由你来确定,不能删掉人有可能在的格子
给出一种方案,使得最后只剩下一个格子
这题是构造……最不喜欢这种题了……
如果走的步数是偶数,那么有可能回到出发点,这样显然不好,因为有可能你永远删不了出发点……所以除了第一步以外,尽量走奇数步
然后把棋盘黑白染色,如果走奇数步就可以保证出发和落脚点的颜色不同
有一个很简单的构造就是在第一步把所有不可能走到的位于右下角的格子删去,然后每次删一条对角线,
打个比方
如果人在白格子上,那么走完之后肯定在黑格子上,不会影响我删这条白色对角线,而且由于对角线在边缘,删去以后也不会导致人的可能的位置不连通
最后就能把人“逼”到左上角