刚刚试了1088题(http://acm.pku.edu.cn/JudgeOnline/problem?id=1088),刚开始用以下算法:先寻找“凸出点”(所谓凸出点是指比上下左右都要高的点,然后广度优先遍历)是用Java实现,我肯定答案是对的,但是超时了。当然这种算法笨了很多。后来看看Discuss,看到用递归实现(62ms)。后来我用Java同样用递归实现之,虽然AC了,不过Time1300多ms,郁闷……看来Java比C++确实慢了不少(尤其这种有数组的,Java进行越界检查……),用Java来做题目效率上比较吃亏。呵呵,反正现在是玩玩而已,先不管了。
附源码:
最初算法:
import java.util.LinkedList;
import java.util.Scanner;
public class Main2 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
int r = Integer.parseInt(scan.next());
int c = Integer.parseInt(scan.next());
int [][]m = new int[r][c];
for(int y=0;y<r;y++)
for(int x=0;x<c;x++){
m[y][x] = Integer.parseInt(scan.next());
}
System.out.println(getResult(m));
}
public static int getResult(int [][]m){
LinkedList<Point> ll = new LinkedList<Point>();
int row = m.length;
int col = m[0].length;
for(int y=0;y<row;y++){
for(int x=0;x<col;x++)
{
//up
if(y>0&&m[y-1][x]>m[y][x])continue;
//down
if(y<row-1&&m[y+1][x]>m[y][x])continue;
//left
if(x>0&&m[y][x-1]>m[y][x])continue;
//right
if(x<col-1&&m[y][x+1]>m[y][x])continue;
ll.addLast(new Point(y,x));
}
}
int max = 1;
while(!ll.isEmpty()){
Point p = ll.removeFirst();
int r = longestFrom(m,p);
if(r>max)max=r;
}
return max;
}
static class Point{
public int x;
public int y;
public Point(int y,int x){
this.y = y;
this.x = x ;
}
}
public static int longestFrom(int [][]m, Point p){
int row = m.length;
int col = m[0].length;
int [][]m2 = new int[row][col];
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
m2[i][j]=1;
LinkedList<Point> ll = new LinkedList<Point>();
ll.addLast(p);
Point pp = new Point(0,0);
while(!ll.isEmpty()){
Point tp = ll.removeFirst();
int value = m2[tp.y][tp.x];
//left
if(tp.x>0 && m[tp.y][tp.x-1]<m[tp.y][tp.x]){
if(m2[tp.y][tp.x-1]<value+1){
m2[tp.y][tp.x-1]=value+1;
ll.addLast(new Point(tp.y,tp.x-1));
}
}
//right
if(tp.x<col-1 && m[tp.y][tp.x+1]<m[tp.y][tp.x]){
if(m2[tp.y][tp.x+1]<value+1){
m2[tp.y][tp.x+1]=value+1;
ll.addLast(new Point(tp.y,tp.x+1));
}
}
//up
if(tp.y>0 && m[tp.y-1][tp.x]<m[tp.y][tp.x]){
if(m2[tp.y-1][tp.x]<value+1){
m2[tp.y-1][tp.x]=value+1;
ll.addLast(new Point(tp.y-1,tp.x));
}
}
//down
if(tp.y<row-1 && m[tp.y+1][tp.x]<m[tp.y][tp.x]){
if(m2[tp.y+1][tp.x]<value+1){
m2[tp.y+1][tp.x]=value+1;
ll.addLast(new Point(tp.y+1,tp.x));
}
}
}
int max = 1;
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
{
if(m2[i][j] > max)
max = m2[i][j];
}
return max;
}
}
改为递归后的Java版本:
import java.util.Scanner;
public class Main {
/**
* @param args
*/
static int [][]m;
static int [][]max;
static int rows;
static int cols;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
rows = Integer.parseInt(scan.next());
cols = Integer.parseInt(scan.next());
m = new int[rows][cols];
max = new int[rows][cols];
for(int y=0;y<rows;y++)
for(int x=0;x<cols;x++){
m[y][x] = scan.nextInt();
}
int maxresult= 0;
int t;
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++){
t=maxLength(i,j);
if(t>maxresult)maxresult = t;
}
System.out.println(maxresult);
}
static int maxLength(int r,int c){
if(max[r][c]>0)return max[r][c];
int temp[] = new int[]{1,1,1,1};
//up
if(r>0 && m[r-1][c]<m[r][c]){
temp[0] = maxLength(r-1,c)+1;
}
//down
if(r<rows-1 && m[r+1][c]<m[r][c]){
temp[1] = maxLength(r+1,c)+1;
}
//left
if(c>0 && m[r][c-1]<m[r][c]){
temp[2] = maxLength(r,c-1)+1;
}
//right
if(c<cols-1 && m[r][c+1]<m[r][c]){
temp[3] = maxLength(r,c+1)+1;
}
int result = temp[0];
for(int i=1;i<4;i++){
if(temp[i]>result)result=temp[i];
}
max[r][c] = result;
return result;
}
}
改为递归后的c++版本:
#include <iostream> using namespace std; //算法比较简明,就是搜索加数据存储 bool flags[100][100]; int max[100][100]; int elements[100][100]; int m, n; int maxlength(int i, int j) { if(max[i][j] >= 0) return max[i][j]; int temp[4] = {0}; if(i > 0 && elements[i][j] > elements[i - 1][j]) { temp[0] = maxlength(i - 1, j) + 1; flags[i - 1][j] = false; } if(j > 0 && elements[i][j] > elements[i][j - 1]) { temp[1] = maxlength(i, j - 1) + 1; flags[i][j - 1] = false; } if(j < n - 1 && elements[i][j] > elements[i][j + 1]) { temp[2] = maxlength(i, j + 1) + 1; flags[i][j + 1] = false; } if(i < m - 1 && elements[i][j] > elements[i + 1][j]) { temp[3] = maxlength(i + 1, j) + 1; flags[i + 1][j] = false; } int result = temp[0]; for(int k = 1; k < 4; ++ k) if(result < temp[k]) result = temp[k]; max[i][j] = result; return result; } int main() { int i; cin >> m >> n; for(i = 0; i < m; ++ i) for(int j = 0; j < n; ++ j) { cin >> elements[i][j]; max[i][j] = -1; flags[i][j] = true; } int nmax = 0; for(i = 0; i < m; ++ i) for(int j = 0; j < n; ++ j) if(flags[i][j]) { maxlength(i, j); if(nmax < max[i][j]) nmax = max[i][j]; } cout << nmax + 1 << endl; return 0; }