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
输入的第一行是两个正整数n和m。接着是n行m列的人生棋盘。
Output
输入只有一列,如果存在合法序列,则为n+m-1个用一个空格隔开的权值。否则就输出Oh,the life is too difficult!
Sample Input
输入1:
3 3
1 3 4
7 9 0
5 6 8
输入2:
2 3
1 0 3
0 4 5
Sample Output
输出1:
1 3 9 6 8
输出2:
Oh,the life is too difficult!
Data Constraint
对于 20% 的数据
n<10,m<10
对于 60% 的数据
n≤300,m≤300
对于 100% 的数据
n≤1000,m≤1000,Aij≤109
Solution
这题相对简单,一眼就是贪心了!
但是走的时候可能进了一个死胡同,这怎么处理呢?
于是我们想到从终点出发,把遍历到的点标记一遍
那么如果起点没被标记就无解了
之后就可以放心从起点开始暴力遍历了,即选较小且被标记的那边走,这样答案保证最优
时间复杂度显然就是 O(N2) !
Code
#include<cstdio>
using namespace std;
const int N=1002;
int a[N][N];
bool f[N][N];
inline int read()
{
int data=0; char ch=0;
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
return data;
}
int main()
{
int n=read(),m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j]=read();
f[n][m]=true;
for(int i=n;i;i--)
for(int j=m;j;j--)
{
if(!a[i][j])
{
f[i][j]=false;
continue;
}
if(i==n && j==m) continue;
f[i][j]=f[i+1][j]|f[i][j+1];
}
if(!f[1][1])
{
printf("Oh,the life is too difficult!");
return 0;
}
int x=1,y=1;
while(x!=n || y!=m)
{
printf("%d ",a[x][y]);
if(!f[x][y+1] || y+1>m) x++; else
if(!f[x+1][y] || x+1>n) y++; else
{
if(a[x][y+1]<a[x+1][y]) y++; else x++;
}
}
printf("%d",a[n][m]);
return 0;
}