hdoj 5402 Travelling Salesman Problem

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5402

类似于黑白棋盘,有的格子是可以不走的,有的格子是不能不走的,对于m或n中有一个奇数的情况,

所有的数都可以走到,当m和n都是偶数的时候,则需要分情况讨论,两行缩成一行走,

从而走遍可以走的数。m=1且n=1的时候需要特判

  1 #include<stdio.h>
  2 #include<cstring>
  3 const int MAXN = 105;
  4 int main(){
  5     int n, m;
  6     int sum;
  7     int maze[MAXN][MAXN];
  8 //    freopen("e.txt","r",stdin);
  9     while(~scanf("%d%d",&n,&m)){
 10         sum = 0;
 11         memset(maze,0,sizeof(maze));
 12         for( int i = 0; i < n; ++i){
 13             for( int j = 0; j < m; ++j){
 14                 scanf("%d",&maze[i][j]);
 15                 sum += maze[i][j];
 16             }
 17         }
 18         if( n == 1 && m == 1){
 19             printf("%d\n",sum);
 20             printf("R\n");
 21             continue;
 22         }
 23         if( n % 2 == 1 ){
 24             printf("%d\n",sum);
 25             for( int i = 0; i < n; ++i){
 26                 for(int j = 1; j < m; ++j){
 27                     if( m == 1 ){
 28                         printf("D");
 29                         continue;
 30                     }
 31                     if( i % 2 == 0)
 32                         printf("R");
 33                     else
 34                         printf("L");
 35                 }
 36                 if( i < n-1)
 37                     printf("D");
 38             }
 39             printf("\n");
 40             continue;
 41         }
 42         else if( m % 2 == 1 ){
 43             printf("%d\n",sum);
 44             for( int i = 0; i < m; ++i){
 45                 for(int j = 1; j < n; ++j){
 46                     if( i % 2 == 0)
 47                         printf("D");
 48                     else
 49                         printf("U");
 50                 }
 51                 if( i< m-1)
 52                     printf("R");
 53             }
 54             printf("\n");
 55             continue;
 56         }
 57         else{
 58             int _min = 1000;
 59             int pi, pj;
 60             for(int i = 0; i < n; ++i){
 61                 for( int j = 0; j < m; ++j){
 62                     if( (i+j) % 2 == 1 && (maze[i][j] < _min)){
 63                         _min = maze[i][j];
 64                         pi = i;
 65                         pj = j;
 66                     }
 67                 }
 68             }
 69 //            找到最小值
 70             printf("%d\n",sum-_min);
 71             if( pi % 2 == 1 ){
 72                 for( int i = 0; i < pi-1; ++i ){
 73                     for( int j = 0; j < m-1; ++j){
 74                         if( i % 2 == 0)
 75                             printf("R");
 76                         else
 77                             printf("L");
 78                     }
 79                     if( i < n-1)
 80                         printf("D");
 81                 }
 82             }
 83 //            如果是奇数行出现,前pi-2行按规律走
 84             else{
 85                 for( int i = 0; i < pi; ++i ){
 86                     for( int j = 0; j < m-1; ++j){
 87                         if( i % 2 == 0)
 88                             printf("R");
 89                         else
 90                             printf("L");
 91                     }
 92                     if( i < n-1)
 93                         printf("D");
 94                 }
 95             }
 96 //            如果是偶数行出现,前pi-1行按规律走
 97             for( int i = 0; i < pj; ++i){
 98                 if( i % 2 == 0)
 99                     printf("D");
100                 else
101                     printf("U");
102                 printf("R");
103             }
104             if( pj < m - 1 )
105                 printf("R");
106             for( int i = pj+1; i < m; ++i){
107                 if( i % 2 == 1)
108                     printf("D");
109                 else
110                     printf("U");
111                 if( i < m-1)
112                     printf("R");
113             }
114             if( !( pi % 2 == 1 && pi + 1 == n) && !( pi % 2 == 0 && pi + 2 == n ))
115                 printf("D");
116 //                两行变一行
117             if( pi % 2 == 1 ){
118                 for( int i = pi+1; i < n; ++i ){
119                     for( int j = 0; j < m-1; ++j){
120                         if( i % 2 == 1)
121                             printf("R");
122                         else
123                             printf("L");
124                     }
125                     if( i < n-1)
126                         printf("D");
127                 }
128             }
129             else{
130                 for( int i = pi+2; i < n; ++i ){
131                     for( int j = 1; j < m; ++j){
132                         if( i % 2 == 1)
133                             printf("R");
134                         else
135                             printf("L");
136
137                     }
138                     if( i < n-1)
139                         printf("D");
140                 }
141             }
142         }
143         printf("\n");
144     }
145 }
时间: 2024-08-07 17:59:39

hdoj 5402 Travelling Salesman Problem的相关文章

HDOJ 5402 Travelling Salesman Problem 模拟

行数或列数为奇数就能够所有走完. 行数和列数都是偶数,能够选择空出一个(x+y)为奇数的点. 假设要空出一个(x+y)为偶数的点,则必须空出其它(x+y)为奇数的点 Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 747    Accepted Submission(s): 272

构造 - HDU 5402 Travelling Salesman Problem

Travelling Salesman Problem Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5402 Mean: 现有一个n*m的迷宫,每一个格子都有一个非负整数,从迷宫的左上角(1,1)到迷宫的右下角(n,m),并且使得他走过的路径的整数之和最大,问最大和为多少以及他走的路径. analyse: 首先,因为每个格子都是非负整数,而且规定每个格子只能走一次,所以为了使和尽可能大,必定是走的格子数越多越好.这样我们就需

HDU 5402 Travelling Salesman Problem (模拟 有规律)

Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 568    Accepted Submission(s): 200 Special Judge Problem Description Teacher Mai is in a maze with n rows and m colum

HDU 5402 Travelling Salesman Problem (构造)(好题)

大致题意:n*m的非负数矩阵,从(1,1) 只能向四面走,一直走到(n,m)为终点,路径的权就是数的和,输出一条权值最大的路径方案 思路:由于这是非负数,要是有负数就是神题了,要是n,m中有一个是奇数,显然可以遍历,要是有一个偶数,可以画图发现,把图染成二分图后,(1,1)为黑色,总能有一种构造方式可以只绕过任何一个白色的点,然后再遍历其他点,而绕过黑色的点必然还要绕过两个白色点才能遍历全部点,这是画图发现的,所以找一个权值最小的白色点绕过就可以了, 题解给出了证明: 如果n,mn,m都为偶数,

HDU 5402 Travelling Salesman Problem(棋盘染色 构造 多校啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5402 Problem Description Teacher Mai is in a maze with n rows and m columns. There is a non-negative number in each cell. Teacher Mai wants to walk from the top left corner (1,1) to the bottom right corn

hdu 5402 Travelling Salesman Problem

题意:从一个方格的左上角走到右下角,拿起经过的全部数字,且每一个方格最多仅仅能走一次,问,终于到达右下角时,sum最大是多少. 做法:--非常显然构造了 首先假设nn为奇数或者mm为奇数,那么显然能够遍历整个棋盘. 如果n,mn,m都为偶数,那么将棋盘黑白染色,如果(1,1)(1,1)和(n,m)(n,m)都为黑色,那么这条路径中黑格个数比白格个数多11.而棋盘中黑白格子个数同样.所以必定有一个白格不会被经过,所以选择白格中权值最小的不经过. 构造方法是这样.首先RRRRDLLLLD这种路径走到

hdu 5402 Travelling Salesman Problem (构造)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5402 题意:给定N*M的矩阵,每一格子里面有一个非负整数,求从(1,1)到(n,m)这条路上的和,(每个格子只能走一次,求最大的和). 分析:官方题解当N为奇数或M为奇数时,可以遍历到所有格子.当N和M都为偶数的时候,那么讲棋盘黑白染色,假设 (1,1)(1,1)和(n,m)(n,m)都为黑色,那么这条路径中黑格个数比白格个数多11,而棋盘中黑白格子个数相同,所以必然有一个白格不会被经过,所以选择白格中

hdu 5402 Travelling Salesman Problem (技巧) 未写完-------------------------------

题意:给一个n*m的矩阵,每个格子中有一个数字,每个格子仅可以走一次,问从(1,1)走到(n,m) 的路径点权之和. 思路: 想了挺久,就是有个问题不能短时间证明,所以不敢下手. 显然只要n和m其中一个是奇数,逐行/列绕就可以到达终点,可是恰好都是偶数呢?由于绕不到,那至少得舍弃1个,但是弃哪个比较好?况且有些格子是弃不了的(画4*4的模拟就知道了). 通过画图可以知道(自己绕!),行号+列号为奇数的格子都是可以舍弃的,而且可以保证其他所有格子都能走一遍到终点(无论是从行/列为单位来绕,这个图都

HDU 5402 Travelling Salesman Problem (MUT#9 暴力模拟)

[题目链接]click here~~ [题目大意]:走方格,从[1,1]到[n,m],求中间过程得到的数字和最大,并且输出路径 [思路]: 如果n和m里面有一个是奇数那么全部走遍就好了. 否则要找一个最小的点不要,这个点的坐标要满足x+y是奇数 如果不是的话,舍弃该点一定会导致另外一个点也走不到. 然后找到这个点,暴力输出路径即可. 代码: #include <bits/stdc++.h> using namespace std; const int N=105; typedef long l