题目链接:zoj 3823 Excavator Contest

题目大意:一个人开着挖掘机要在N*N的格子上面移动。要求走全然部的格子。而且转完次数要至少为n*(n-1) - 1次,

而且终点和起点必须都在边界上。

解题思路:构造。由于终点和起点必须在边界上,进去的同一时候得留出一条路径出来。

  • 奇数

  • 偶数

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2VzaHVhaTE5OTQwNzIy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

奇数的情况分两种(图上两点所代表的正方形构造方式是一样的。即13。9为一类,11。7为一类)

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2VzaHVhaTE5OTQwNzIy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

偶数分为四类(图上两点所代表的正方形构造方式是不一样的,即14,12,10,8各为一类)



watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2VzaHVhaTE5OTQwNzIy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2VzaHVhaTE5OTQwNzIy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

这是我做过最恶心的构造题了。

#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;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

zoj 3823 Excavator Contest(结构体)的更多相关文章

  1. zoj 3823 Excavator Contest 构造

    Excavator Contest Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...

  2. HDOJ 1009. Fat Mouse' Trade 贪心 结构体排序

    FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  3. 初次见识结构体与map的区别

    题目  http://vjudge.net/contest/view.action?cid=51142#problem/G 自己做的结构体 #include <iostream>#incl ...

  4. Go结构体实现类似成员函数机制

    Go语言结构体成员能否是函数,从而实现类似类的成员函数的机制呢?答案是肯定的. package main import "fmt" type stru struct { testf ...

  5. C#基础回顾(二)—页面值传递、重载与重写、类与结构体、装箱与拆箱

    一.前言 -孤独的路上有梦想作伴,乘风破浪- 二.页面值传递 (1)C#各页面之间可以进行数据的交换和传递,页面之间可根据获取的数据,进行各自的操作(跳转.计算等操作).为了实现多种方式的数据传递,C ...

  6. go语言结构体

    定义: 是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体. 成员: 每个值称为结构体的成员. 示例: 用结构体的经典案例处理公司的员工信息,每个员工信息包含一个唯一的员工编号.员工的名字. ...

  7. C语言中的结构体

    用户自己建立自己的结构体类型 1.  定义和使用结构体变量 (1).结构体的定义 C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体. (2).声明一个结构体类型的一般形式为: ...

  8. C++_系列自学课程_第_12_课_结构体

    #include <iostream> #include <string> using namespace std; struct CDAccount { double bal ...

  9. java socket传送一个结构体给用C++编写的服务器解析的问题

    另一端是Java写客户端程序,两者之间需要通信.c++/c接收和发送的都是结构体,而Java是直接发送的字节流或者byte 数组.解决方法:c++/c socket 在发送结构体的时候其实发送的也是字 ...

随机推荐

  1. 11gR2更换OCR和VOTE

    11gR2开始,OCR和VOTE它们被存储在ASM磁盘组,因此,更换OCR有两种方法,第一是使用ASM磁盘组drop disk数据重组后,另一种方法是OCR迁移到另一个磁盘组 第一种:add disk ...

  2. window忘记密码怎么办

    net命令   Net User 功能:添加或更改用户帐号或显示用户帐号信息. 格式:net user [username [password | *] [options]] [/domain] ne ...

  3. 写你自己struts1框架

    前言 文本 它们的定义Struts1 commons-digester.jar解析XML 实现XML标签到对象的转换 1.依据目标XML的结构定义解析规则文件 參照rule.xml 2.创建集合对象接 ...

  4. Directx11学习笔记【九】 【转】 3D渲染管线

    原文地址:http://blog.csdn.net/bonchoix/article/details/8298116 3D图形学研究的基本内容,即给定场景的描述,包括各个物体的材质.纹理.坐标等,照相 ...

  5. JMS and ActiveMQ first lesson(转)

    JMS and ActiveMQ first lesson -- jms基础概念和应用场景 2011-6-18 PM 9:30 主讲:kimmking <kimmking@163.com> ...

  6. 【DataStructure】Some useful methods about linkedList(三)

    Method 4: Gets the value of element number i For example, if list is {22, 33, 44, 55, 66, 77, 88, 99 ...

  7. UNITY3D MAC版本号破解

    首先,解释一下.是公司做开发建议去购买正版. 之前网上也有非常多人贴出了破解方法,有些也是能够的.可是大多数解说不太具体,在这里贴出相对具体点的教程.本人亲測成功(測试版本Unity4.0.1 mac ...

  8. Source insight 3572安装和版本号An invalid source insight serial number was detected解

    Source insight最新版本3572 下载链接:http://www.sourceinsight.com/down35.html,   http://www.sourceinsight.com ...

  9. 系列二VS项目软件配置工具介绍

    原文:系列二VS项目软件配置工具介绍 Svn和VisualSvn介绍 在使用TortoiseSvn(SVN客户端)+ AnkhSvn(VS2008插件) +VisualSvn Server(版本控制服 ...

  10. 比NotePad++更好的文本代码(C#)编辑器Sublime Text

    原文:比NotePad++更好的文本代码(C#)编辑器Sublime Text 前言 前两天在博客园看到@晴天猪的博客发表的关于他使用的代码编辑器,自己索性试了一下,果断好用,自己也来记录一下.以便以 ...