无
2015-09-10 16:14
417 查看
Problem A
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65535/65535K (Java/Other)Total Submission(s) : 80 Accepted Submission(s) : 15
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Zyh相信自己想要的幸福在不远处。然而,zyh想要得到这幸福,还需要很长的一段路。Zyh坚持认为整个人生可以抽象为一个n*m的棋盘。左上角的格子为(1,1),右下角的格子为(n,m)。整个棋盘上的格子都有不同的事件,因为生活的多姿多彩,事件的权值Aij都两两不同。不幸的是,在整个人生中有若干个极其黑暗的事件,它们的权值Aij=0。更进一步说,对于Aij>0的事件,权值两两不同。Zyh站在人生的起点(1,1),他想要走向人生的巅峰(n,m)。Zyh认为人只能前进,即若Zyh站在(a,b),他只能走向(a,b+1)或者(a+1,b)。并且Zyh认为黑暗的事件是绝对不可以触碰的,因为一旦经历就会坠入万丈深渊。Zyh会将自己所经历的事件的权值依次写出,形成一个n+m-1的序列。Zyh想知道其中字典序最小的序列是什么。若是人生过于艰难,没有一个合法序列,就输出”Oh,the life is too difficult!”,不包含引号。
Input
输入的第一行是组数T。输入的第二行是两个正整数n和m。接着是n行m列的人生棋盘。
Output
输入只有一列,如果存在合法序列,则为n+m-1个用一个空格隔开的权值。否则就输出Oh,the life is too difficult!Sample Input
2 3 3 1 3 4 7 9 0 5 6 8 2 3 1 0 3 0 4 5
Sample Output
1 3 9 6 8 Oh,the life is too difficult!
Hint
对于20%的数据 n<10 m<10对于60%的数据 n<=300 m<=300
对于100%的数据 n<=1000 m<=1000 Aij<=1e9
T<=10
本题可以先进行预处理,判断哪些点能走到终点,
所以只需要找两边(下和右)哪个较小,便走哪个
#include <queue> #include <cmath> #include <ctime> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f #define inf -0x3f3f3f3f #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mem0(a) memset(a,0,sizeof(a)) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a, b) memset(a, b, sizeof(a)) typedef long long ll; int mp[1010][1010]; int vis_front[1010][1010]; int vis[1010][1010]; const int BUF=40000010; char Buf[BUF],*buf=Buf; inline void read(int&a){ for(a=0;*buf<48;buf++); while(*buf>47) a=a*10+*buf++-48;} int main(){ fread(Buf,1,BUF,stdin); int t; read(t); int n,m; while(t--){ read(n); read(m); int x,y; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(mp[i][j]); mem0(vis_front); if(mp[1][1]==0||mp [m]==0){ printf("Oh,the life is too difficult!\n"); continue; } for(int i=1;i<=n;i++) //从前走到后 for(int j=1;j<=m;j++){ if(i==1&&j==1){ vis_front[1][1]=1; } else if(i==1){ if(mp[i][j]!=0&&vis_front[i][j-1]) vis_front[i][j]=1; } else if(j==1){ if(mp[i][j]!=0&&vis_front[i-1][j]) vis_front[i][j]=1; } else{ if(mp[i][j]!=0&&(vis_front[i-1][j]||vis_front[i][j-1])) vis_front[i][j]=1; } } if(vis_front [m]==0){ printf("Oh,the life is too difficult!\n"); continue; } mem0(vis); for(int i=n;i>=1;i--) for(int j=m;j>=1;j--){ if(i==n&&j==m){ vis [m]=1; } if(vis_front[i][j]==1&&vis[i][j]==1){ if(vis_front[i-1][j]==1) vis[i-1][j]=1; if(vis_front[i][j-1]==1) vis[i][j-1]=1; } } printf("%d",mp[1][1]); for(int i=1;i<n+m-1;i++){ if(i==1){ x=y=1; } if(x+1<=n&&y+1<=m){ if(vis[x][y+1]==1&&vis[x+1][y]==1){ if(mp[x][y+1]<mp[x+1][y]){ printf(" %d",mp[x][y+1]); y++; } else{ printf(" %d",mp[x+1][y]); x++; } } else if(vis[x][y+1]==1){ printf(" %d",mp[x][y+1]); y++; } else if(vis[x+1][y]==1){ printf(" %d",mp[x+1][y]); x++; } } else if(x+1<=n&&vis[x+1][y]==1){ printf(" %d",mp[x+1][y]); x++; } else if(y+1<=n&&vis[x][y+1]==1){ printf(" %d",mp[x][y+1]); y++; } } printf("\n"); } return 0; }
相关文章推荐
- 面试题之求两个字符串的最大公共子串
- 【基础】1.原码、反码、补码
- AI小技巧—花朵
- 转载:天涯——散文天下——《小驴坑爹记》——作者:南方孤驴
- 卡尔曼滤波(KF)和扩展卡尔曼滤波(EKF)
- navigation的pushViewController卡顿问题
- 各类JavaScript插件
- 【超级表格创业谱】苏元:创业是一场豪赌,赌注是整个青春。
- 安装rz,sz
- Ubuntu下android adb环境变量配置方法
- 初学c#中的委托
- manacher算法
- CRC算法原理
- c#中使用轻量级数据库sqlite开发总结
- android新技术之RecyclerView使用
- Asp.Net 小型网站的制作(一),涵盖了asp.net里面所有的基础知识
- ARM板烧录LinuxQt程序步骤
- spark-streaming系列------- 1. spark-streaming的Job调度 上
- flash AS3.0访问加载的SWF文件中的属性、方法以及类、库中的影片剪辑
- Struts2 实战(一)