zoj 3823 Excavator Contest(结构体)
2015-08-14 15:48
288 查看
题目链接:zoj 3823 Excavator Contest
题目大意:一个人开着挖掘机要在N*N的格子上面移动。要求走全然部的格子。而且转完次数要至少为n*(n-1) - 1次,
而且终点和起点必须都在边界上。
解题思路:构造。由于终点和起点必须在边界上,进去的同一时候得留出一条路径出来。
奇数
偶数
奇数的情况分两种(图上两点所代表的正方形构造方式是一样的。即13。9为一类,11。7为一类)
偶数分为四类(图上两点所代表的正方形构造方式是不一样的,即14,12,10,8各为一类)
这是我做过最恶心的构造题了。
题目大意:一个人开着挖掘机要在N*N的格子上面移动。要求走全然部的格子。而且转完次数要至少为n*(n-1) - 1次,
而且终点和起点必须都在边界上。
解题思路:构造。由于终点和起点必须在边界上,进去的同一时候得留出一条路径出来。
奇数
偶数
奇数的情况分两种(图上两点所代表的正方形构造方式是一样的。即13。9为一类,11。7为一类)
偶数分为四类(图上两点所代表的正方形构造方式是不一样的,即14,12,10,8各为一类)
这是我做过最恶心的构造题了。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 550; const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; //const int G[5][50] = {{0}, {0}, {3, 4, 2, 1}, {5, 6, 9, 4, 7, 8, 3, 2, 1}}; const int dir_down[4][4][4] = { {{3, 1, 2, 1}, {3, 3, 0, 3}, {1, 3, 0, 3}, {1, 3, 0, 0}}, {{2, 1, 3, 1}, {2, 1, 3, 3}, {0, 3, 1, 3}, {3, 0, 2, 0}}, {{3, 1, 2, 1}, {1, 3, 0, 3}, {1, 3, 0, 0}} }; const int dir_left[5][4] = { {1, 2, 0, 2}, {1, 2, 0, 2}, {2, 1, 3, 1}, {0, 2, 1, 2}, {0, 2, 1, 1}}; const int dir_up[5][4] = { {2, 0, 3, 0}, {2, 0, 3, 0}, {0, 2, 1, 2}, {3, 0, 2, 0}, {3, 0, 2, 2} }; int L, R, g[maxn][maxn]; void put(int n); inline void jump(int n, int& x, int& y, int& mv, int len, const int d[4]) { for (int i = 0; i < n; i++) { for (int j = 0; j < 4; j++) { g[x][y] = mv; mv += len; x += dir[d[j]][0]; y += dir[d[j]][1]; } } } inline void moveup(int n, int& x, int& y, int& mv, int len) { //printf("moveup:%d\n", len); if (n&1) { jump(n / 2 - 1, x, y, mv, len, dir_up[0]); for (int t = 0; t < 2; t++) { g[x][y] = mv; x += dir[2][0]; y += dir[2][1]; mv += len; } } else if ((n/2) % 4) { jump(n / 2 - 2, x, y, mv, len, dir_up[1]); jump(1, x, y, mv, len, dir_up[2]); } else { jump(n / 2 - 2, x, y, mv, len, dir_up[3]); jump(1, x, y, mv, len, dir_up[4]); } } inline void moveleft(int n, int& x, int& y, int& mv, int len) { //printf("moveleft:%d\n", len); if (n&1) { jump(n / 2, x, y, mv, len, dir_left[0]); for (int t = 0; t < 2; t++) { // down twice; g[x][y] = mv; x += dir[1][0]; y += dir[1][1]; mv += len; } } else if ((n/2) % 4) { jump(n / 2 - 1, x, y, mv, len, dir_left[1]); jump(1, x, y, mv, len, dir_left[2]); } else { jump(n / 2 - 1, x, y, mv, len, dir_left[3]); jump(1, x, y, mv, len, dir_left[4]); } } inline void movedown(int n, int& x, int& y, int& mv, int len) { int p; //printf("movedown!\n"); if (n&1) { for (int k = 0; k < 4; k++) { if (k == 0) p = n / 2; else if (k == 1 || k == 3) p = 1; else p = n / 2 - 2; jump(p, x, y, mv, len, dir_down[0][k]); } } else if ((n/2) % 4 == 1) { for (int k = 0; k < 4; k++) { if (k == 0) p = n / 2 - 1; else if (k == 1 || k == 3) p = (n == 2 && k == 3 ? 0 : 1); else p = max(n / 2 - 2, 0); jump(p, x, y, mv, len, dir_down[1][k]); } } else { for (int k = 0; k < 3; k++) { if (k == 0 || k == 1) p = n / 2 - 1; else p = 1; jump(p, x, y, mv, len, dir_down[2][k]); } } } void solve (int n, int sx, int sy, int ex, int ey, int flag) { if (n <= 1) { if (n == 1) g[sx][sy] = L; return; } /* printf("%d:\n", n); put(10); */ if (n&1) { if ((n/2)&1) { if (flag) { moveup(n, sx, sy, L, 1); moveleft(n, ex, ey, R, -1); } else { moveup(n, ex, ey, R, -1); moveleft(n, sx, sy, L, 1); } solve(n - 2, sx, sy, ex, ey, flag); } else { if (flag) movedown(n, ex, ey, R, -1); else movedown(n, sx, sy, L, 1); solve(n - 2, sx, sy, ex, ey, flag^1); } } else { if ((n/2)&1) { if (flag) movedown(n, ex, ey, R, -1); else movedown(n, sx, sy, L, 1); solve(n - 2, sx, sy, ex, ey, flag^1); } else { if (flag) { moveup(n, sx, sy, L, 1); moveleft(n, ex, ey, R, -1); } else { moveup(n, ex, ey, R, -1); moveleft(n, sx, sy, L, 1); } solve(n - 2, sx, sy, ex, ey, flag); } } } void put (int n) { for (int i = 1; i <= n; i++) { printf("%d", g[i][1]); for (int j = 2; j <= n; j++) printf(" %d", g[i][j]); printf("\n"); } } int main () { int cas, n; scanf("%d", &cas); while (cas--) { scanf("%d", &n); int sx, sy, ex, ey, flag; L = 1, R = n * n; if (n&1) { if ((n/2)&1) ex = 1, ey = sx = sy = n, flag = 1; else sx = sy = ex = 1, ey = n, flag = 0; } else { int t = n / 2; t = (t - 1) % 4 + 1; if (t == 1) sx = 1, sy = ex = 2, ey = n, flag = 0; else if (t == 2) sx = sy = ey = n, ex = 1, flag = 1; else if (t == 3) sx = sy = ex = 1, ey = n, flag = 0; else sx = ey = n, sy = n - 1, ex = 2, flag = 1; } //printf("%d %d %d %d %d!!!\n", sx, sy, ex, ey, flag); solve(n, sx, sy, ex, ey, flag); put(n); } return 0; }
相关文章推荐
- Android主页导航:fragment+viewpager
- Lua.LearningLua.5-document-for-luaL_findtable-function
- Android基于mAppWidget实现手绘地图(十一)–移动地图到某个坐标
- Centos6 Postfix+Dovecot+Postfixadmin+Roundcube 搭建Webmail邮件系统
- C语言中两个实用的宏定义__DATE__和__TIME__
- Hibernate中多对多的annotation的写法(中间表可以有多个字段)
- 119 Pascal's Triangle II
- linux系统下无法创建mysql存储过程问题
- java设计模式之一 —— 工厂模式整理
- C#实现自定义Dictionary类实例
- Redis常用的命令(三)------字符串
- 数据结构实验之求二叉树后序遍历和层次遍历
- spring_jar包的详解
- H - Sum---(2015 summer training #12(Team_Qualifying))
- 服务器配置sqlserver远程连接
- servletFileUpload.parseRequest(request)解析为空获取不到数据问题
- 国际象棋跳马程序(自编码研究)
- 如何写一个简单的linux驱动
- Java连接MySQL中文乱码处理
- Java集合类操作优化经验总结