题意:

有一个n * m的数字矩阵,每个格子放着一个非负整数,从左上角走到右下角,每个格子最多走一次,问所经过的格子的最大权值之和是多少,并且输出一个路径。

分析:

如果n和m有一个是偶数的话,那么只要按照蛇形的走法一直走下去即可。

比如n为奇数的时候就这样,左右左右地蛇形走。

同样的,如果m为奇数的时候,也可以上下上下地蛇形走。

但如果n和m都为偶数的时候,就会无法走完全部的格子,最终到达右下角。

但是可以少走一个格子,而且这个格子必须是那种行标加列标为奇数的格子才行(行和列从1开始),所以我们就绕过权值最小的符合条件的格子,走其他所有的格子获得最大值。

比如像这种:

除了那个选出来的格子不走,其余的格子可以全部走到。

所以就直接这样构造出一条路径出来。

我们可以这样构造,假设选出来的不走的格子为(x, y),把这个地图分成三部分:选第x行和相邻的一行,这两个作为一个「长城」的走法。

然后「长城」上面和下面用蛇字形走法,最后走到右下角。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ; int n, m, sum, _min;
int a[maxn][maxn]; int r, c; bool vis[maxn][maxn]; void snake(int n, int m, char d, char revd, char nxt)
{
for(int i = ; i <= n; i++)
{
if(i & )
{
for(int j = ; j < m; j++) printf("%c", d);
if(i < n) printf("%c", nxt);
}
else
{
for(int j = ; j < m; j++) printf("%c", revd);
if(i < n) printf("%c", nxt);
}
}
} int main()
{
while(scanf("%d%d", &n, &m) == && n)
{
sum = ;
_min = ;
for(int i = ; i <= n; i++)
for(int j = ; j <= m; j++)
{
scanf("%d", &a[i][j]);
sum += a[i][j];
if(((i + j) & ) && a[i][j] < _min) { _min = a[i][j]; r = i; c = j; }
} if(n & )
{
printf("%d\n", sum);
snake(n, m, 'R', 'L', 'D');
puts("");
continue;
} if(m & )
{
printf("%d\n", sum);
snake(m, n, 'D', 'U', 'R');
puts("");
continue;
} printf("%d\n", sum - _min); if(r - > ) snake(r - , m, 'R', 'L', 'D');
if(r - > ) printf("D"); int x, y, up, down;
if(r <= )
{
x = y = ;
up = , down = ;
}
else
{
up = r - , down = r;
x = r - ;
if(r & ) y = m; else y = ;
} memset(vis, false, sizeof(vis));
for(int i = ; i <= n + ; i++) vis[i][] = vis[i][m + ] = true;
for(int i = ; i <= m + ; i++) vis[][i] = vis[n + ][i] = true;
vis[x][y] = true;
vis[r][c] = true;
if(y == )
{
for(int i = ; i <= m * - ; i++)
{
if(x == down)
{
if(!vis[x-][y]) { x--; vis[x][y] = true; printf("U"); }
else { y++; vis[x][y] = true; printf("R"); }
}
else
{
if(!vis[x+][y]) { x++; vis[x][y] = true; printf("D"); }
else { y++; vis[x][y] = true; printf("R"); }
}
}
}
else
{
for(int i = ; i <= m * - ; i++)
{
if(x == down)
{
if(!vis[x-][y]) { x--; vis[x][y] = true; printf("U"); }
else { y--; vis[x][y] = true; printf("L"); }
}
else
{
if(!vis[x+][y]) { x++; vis[x][y] = true; printf("D"); }
else { y--; vis[x][y] = true; printf("L"); }
}
}
} if(down + <= n)
{
printf("D");
if(y == ) snake(n - down, m, 'R', 'L', 'D');
else snake(n - down, m, 'L', 'R', 'D');
} puts("");
} return ;
}

代码君

最新文章

  1. google play下载apk
  2. yii create url (二)
  3. js弹出提示信息,然后跳转到另一页面
  4. 基于能量收集的智能家居-2013国家级大学生创业实践项目申报_商业计划书_V0.2
  5. Microsoft 2013 新技术学习笔记 一
  6. Linux是怎么启动的
  7. Android窗口为弹出框样式
  8. C#手动回收内存的简单方法
  9. es5 和 es6 class
  10. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
  11. houseAPP
  12. mybatis基础(上)
  13. html css col-md-offset
  14. Writing and playing with custom Terraform Providers
  15. python——简单爬虫
  16. Elasticsearch Query DSL 整理总结(一)—— Query DSL 概要,MatchAllQuery,全文查询简述
  17. Coursera台大机器学习技法课程笔记13-Deep Learning
  18. scala -- 柯里化
  19. PHP扩展类ZipArchive实现压缩解压Zip文件和文件打包下载 &amp;&amp; Linux下的ZipArchive配置开启压缩 &amp;&amp;搞个鸡巴毛,写少了个‘/’号,浪费了一天
  20. PHP一句话木马Webshell变形免杀总结

热门文章

  1. Java基础(Java概述、环境变量、注释、关键字、标识符、常量)
  2. B/S架构 C/S架构 SOA架构
  3. dubbo rest返回值异常Incompatible types: declared root type
  4. 从typeof()说起
  5. (2017.10.16) javascript 数据类型转换与操作
  6. 【Unity3D】资源对象、预设、查找对象、组合模式等知识点
  7. Ajax经典的面试题
  8. 小常识:变量的修饰符和DEMO
  9. JS中的作用域和作用域链
  10. python 遍历list