http://poj.org/problem?id=1088
滑雪
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 68159 | Accepted: 25100 |
Description
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
Sample Input
5 5 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
Sample Output
25
我自己写的一个代码,感觉有点像记忆化搜索,但又不是。所以我同学有点不理解我的代码。
我后面用我的代码和花姐AC了的代码进行输出对比,中午睡觉前开始,睡觉完了还是没有发现不一样的。。。哭了。。T_T。。
我的思路是从第一个开始一个一个搜索当前能走的最远距离,然后用dp存储最远距离。。(在主函数里面)在搜索时如果走到以前的找到过最远距离的地方时直接加上距离然后就可以返回了。
对比的时候,我的文件名叫wang.cpp,花姐的文件名为lei.cpp,随机输入文件为in.cpp。。
我
自己WA的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map[110][110];
int dp[110][110]; //这个位置能走的最远距离
int maxx,p;
int mark[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
void Dfs(int x, int y, int t)
{
int i,j,q,now;
if(map[x][y] == -1) //到边缘退出
{
return ;
}
if(dp[x][y]!=0) //这条路经已经求出最长,则接下来的不用再搜了,剪枝
{
t = t+dp[x][y];
if(t > p)
{
p = t;
}
return ;
}
t = t+1; //当前这个位置没有求过最优解并且没有离开边界
if(t > p)
{
p = t;
}
for(q = 0; q < 4; q++)
{
i = x+mark[q][0];
j = y+mark[q][1];
if(map[i][j] < map[x][y])
{
now = t;
Dfs(i,j,now);
}
}
return ;
}
int main()
{
int r,c,t,i,j;
while(scanf("%d%d",&r,&c)!=EOF)
{
maxx = 0;
memset(map,-1,sizeof(map));
memset(dp,0,sizeof(dp));
for(i = 1; i <= r; i++)
{
for(j = 1; j <= c; j++)
{
scanf("%d",&map[i][j]);
}
}
for(i = 1; i <= r; i++)
{
for(j = 1; j <= c; j++)
{
t = 0; //清空
p = 0;
Dfs(i,j,t);
dp[i][j] = p; //记录这个位置的最远距离
if(p > maxx)
{
maxx = p;
}
printf("%d ",dp[i][j]);
}
printf("\n");
}
printf("%d\n",maxx);
}
return 0;
}
花姐AC代码:
#include<stdio.h>
int n,m;
int map[100][100];
int lon[100][100];
int dir[4][2]= {1,0,0,1,-1,0,0,-1};
bool inmap(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<m)
return true;
else
return false;
}
int dfs(int x,int y)
{
int nx,ny,i;
int max1=1;
if(lon[x][y]>1)
return lon[x][y];
for(i=0; i<4; i++)
{
nx=x+dir[i][0];
ny=y+dir[i][1];
if(inmap(nx,ny)&&map[x][y]>map[nx][ny])
{
lon[x][y]=dfs(nx,ny)+1;
if(lon[x][y]>max1)
max1=lon[x][y];
}
}
lon[x][y]=max1;
return max1;
}
int main()
{
int i,j;
int longest;
scanf("%d%d",&n,&m);
longest=1;
for(i=0; i<n; i++)
for(j=0; j<m; j++)
{
scanf("%d",&map[i][j]);
lon[i][j]=1;
}
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
int t=dfs(i,j);
longest=longest>t?longest:t;
}
}
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
printf("%d ",lon[i][j]);
}
printf("\n");
}
printf("%d\n",longest);
return 0;
}
随机产生输入数据程序(in)代码:
#include <cstdio>
#include <ctime>
#include <time.h>
#include <cstdlib>
using namespace std;
double radom() //生成[0,1]之间的均匀随机数
{
return (double)rand()/RAND_MAX;
}
//int random(int m)
//{
// return (int)(random()*(m-1)+0.5);
//}
int main()
{
int n,m, i, j, x;
srand(time(NULL)); //散播随机种子(头文件需要time.h和stdlib.h)
n = rand()%100 +1; //产生1到100的随机数并赋值给n
m = rand()%100 +1;
// freopen("in.txt","r",stdout);
printf("%d %d\n",n,m);
// scanf("%d",&n);
for(i=0; i<n; i++){
for(j=0; j<m; j++)
{
x = rand()%100000;
printf("%d ",x);
}
printf("\n");
}
return 0;
}
windows下批处理对比文件指令(用txt写完后改为bat批处理格式):
@echo off
:again
in > input ;in.exe里面的随机数输入到input文件中
lei < input > output.l ;input文件里面的随机数数据输入到lei.exe中并把其得到的结果存放到outputl文件里面
wang <input > output.w ;同上一行
fc output.l output.w ;对比文件outputl和outputw文件
if not errorlevel 1 goto again ;如果两个文件里面的数据相同则继续循环
pause ;否则就暂停
:again
in > input ;in.exe里面的随机数输入到input文件中
lei < input > output.l ;input文件里面的随机数数据输入到lei.exe中并把其得到的结果存放到outputl文件里面
wang <input > output.w ;同上一行
fc output.l output.w ;对比文件outputl和outputw文件
if not errorlevel 1 goto again ;如果两个文件里面的数据相同则继续循环
pause ;否则就暂停
以上所有cpp文件都要进行编译链接后最后再运行批处理文件。。