规律,模拟,贪心(Travelling Salesman Problem,HDU 5402)
来源:互联网 发布:centos 7 unmount 编辑:程序博客网 时间:2024/06/08 20:02
显然行列有一个是奇数就可以全部走完。这种情况直接模拟就好。
否则的话,一定会有一个格子走不到。
多试几种情况就可以发现这个规律。
证明的话:http://blog.csdn.net/queuelovestack/article/details/47756605
就是对整个棋盘进行黑白二染色,如果行列相加为偶数,就染成黑色,否则染成白色。我们的路径一定是黑白相间。
当行列皆为偶数的时候我们可以发现矛盾。
此时(1,1)是黑色,(n,m)也是黑色。因为路径黑白相间,所以经过的白色格子一定比黑色格子少一个。而整个棋盘中黑白格子的个数是相等的,所以至少有1个白色格子是走不到的。
比赛时不一定能想到严格证明,但若能发现规律,并且有一定把握也是可以的。
至于该如何模拟,看到了网上有很简单的办法,就是随便绕绕就绕过去了,我的模拟就麻烦很多了。
如果可以,尽量想出一些简单的模拟办法,当然能想到自己的办法是好事,但这可能会给编程带来一些麻烦。
希望自己在找到线索之后可以进一步地把它想清楚,从而找到更简单的规律,然后再开始编程。
代码
#include<stdio.h>#include<vector>using namespace std;const int maxn = 110;int n,m;int MAP[maxn][maxn];int mr,mc;vector<char>vec;int ans;int vis[maxn][maxn];void read(){ ans=0; vec.clear(); mr=mc=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { vis[i][j]=0; scanf("%d",&MAP[i][j]); if(!(i==1&&j==1)&&!(i==n&&j==m)&&((i+j)&1)&&MAP[mr][mc]>MAP[i][j]) { mr=i; mc=j; } }}bool ok(int r,int c){ return 1<=r&&r<=n&&1<=c&&c<=m&&!(r==mr&&c==mc)&&!vis[r][c];}int change(int r,int c,int t){ if(t==0) { if(c==m) return 1; for(int i=1;i<=n;i++) if(ok(i,c+1)&&!vis[i][c+1]) return 0; return 1; } if(t==1) { if(c==1) return n-r<=m-c?2:0; for(int i=1;i<=n;i++) if(ok(i,c-1)&&!vis[i][c-1]) return 1; return n-r<=m-c?2:0; } if(t==2) { if(r==n) return 3; for(int i=1;i<=m;i++) if(ok(r+1,i)&&!vis[r+1][i]) return 2; return 3; } if(t==3) { if(r==1) return n-r<m-c?2:0;; for(int i=1;i<=m;i++) if(ok(r-1,i)&&!vis[r-1][i]) return 3; return n-r<m-c?2:0; } return 0;}void dfs(int r,int c,int t){ ans+=MAP[r][c]; vis[r][c]=1; if(r==n&&c==m) return; t=change(r,c,t); if(t==0) { if(ok(r-1,c)) { vec.push_back('U'); dfs(r-1,c,t); } else if(ok(r,c+1)) { vec.push_back('R'); dfs(r,c+1,t); } else if(ok(r+1,c)) { vec.push_back('D'); dfs(r+1,c,t); } return; } else if(t==1) { if(ok(r-1,c)) { vec.push_back('U'); dfs(r-1,c,t); } else if(ok(r,c-1)) { vec.push_back('L'); dfs(r,c-1,t); } else if(ok(r+1,c)) { vec.push_back('D'); dfs(r+1,c,t); } return; } else if(t==2) { if(ok(r,c-1)) { vec.push_back('L'); dfs(r,c-1,t); } else if(ok(r+1,c)) { vec.push_back('D'); dfs(r+1,c,t); } else if(ok(r,c+1)) { vec.push_back('R'); dfs(r,c+1,t); } return; } else if(t==3) { if(ok(r,c-1)) { vec.push_back('L'); dfs(r,c-1,t); } else if(ok(r-1,c)) { vec.push_back('U'); dfs(r-1,c,t); } else if(ok(r,c+1)) { vec.push_back('R'); dfs(r,c+1,t); } return; }}void handle(){ if(n>=m) dfs(1,1,0); else dfs(1,1,2);}void solve(){ read(); if((n&1)==0&&(m&1)==0); else mr=mc=0; handle(); printf("%d\n",ans); for(int i=0;i<(int)vec.size();i++) printf("%c",vec[i]); puts("");}int main(){ MAP[0][0]=10010; while(~scanf("%d %d",&n,&m)) solve(); return 0;}
阅读全文
0 0
- 规律,模拟,贪心(Travelling Salesman Problem,HDU 5402)
- Travelling Salesman Problem (hdu 5402 模拟)
- HDU-5402 Travelling Salesman Problem(模拟)
- hdu 5402 Travelling Salesman Problem 模拟构造
- hdu 5402 Travelling Salesman Problem(构造+模拟)
- HDU 5402 Travelling Salesman Problem(多校9 模拟)
- hdu(5402)——Travelling Salesman Problem(模拟题)
- HDU 5402 Travelling Salesman Problem (MUT#9 暴力模拟)
- hdu 5402 Travelling Salesman Problem(模拟,棋盘染色问题)
- HDU 5402 Travelling Salesman Problem (模拟 有规律)(左上角到右下角路径权值最大,输出路径)
- 【HDU 5402】Travelling Salesman Problem(构造)
- hdu 5402 Travelling Salesman Problem(构造)
- HDU 5402 Travelling Salesman Problem
- HDU 5402 Travelling Salesman Problem
- hdu 5402 Travelling Salesman Problem
- hdu 5402 Travelling Salesman Problem
- hdu 5402 Travelling Salesman Problem
- HDOJ 5402 Travelling Salesman Problem 模拟
- Glide框架的基本使用
- Android 内存优化
- 欢迎使用CSDN-markdown编辑器
- CodeForces
- CCF中学生计算机程序设计入门篇练习2.3.2(NOI1000 加密算法) pascal
- 规律,模拟,贪心(Travelling Salesman Problem,HDU 5402)
- AndroidStudio NDK支持C++ STL和C++11
- 浅学redis之Jedis
- 2212: [Poi2011]Tree Rotations/3702: 二叉树
- NKOJ-3712 数列<L特供版>
- Thinking in Java 笔记(2017/7/16)
- LinuxC简谈之数组、字符串与指针相关的常见错误与问题
- Java对象数组深拷贝
- 2017.07.16小组赛题目I