您的位置:首页 > 其它

POJ ACM 1154

2010-05-25 21:51 176 查看
这个题目花了我好长的时间,其实思路一直都是对的,不是这里漏了就是那里漏了,现在终于AC了~主要是要注意到返回走另一条路径时会出现一些混乱。下面是一些思路和代码:

#include <iostream>
#include <vector>
using std::vector ;

using namespace std ;

vector<char> letters ; //用来存储已经走过的字符
char a[21][21] ; //存储输入的字符集
int rows = 0 ;
int columns = 0 ;

int static r = 0 ; //记录此时访问的行
int static c = 0 ; //记录此时访问的列

/*如果p[r][c][0]==true即可以往上走,相反为false即不可以往上走
* 如果p[r][c][1]==true即可以往下走,相反为false即不可以往下走
* 如果p[r][c][2]==true即可以往左走,相反为false即不可以往左走
* 如果p[r][c][3]==true即可以往右走,相反为false即不可以往右走
*/
bool p[20][20][4] = {false} ;

/**
*将已经访问的字符的r,c,以及在该点可以走的路径条数分别对应存储到
*tempR,tempC,tempN
*/
vector<int> tempR ;
vector<int> tempC ;
vector<int> tempN ;

int maxCount = 1 ;
int count = 0 ;

int findWay(int , int); //找到该字符所可以走的路径条数
bool isUp(int , int); //判断是否可以往上走
bool isDown(int , int); //判断是否可以往下走
bool isLeft(int , int) ; //判断是否可以往左走
bool isRight(int , int); //判断是否可以往右走

void startGo(int , int); //根据当前的字符,选择合适的下一条路径走
void goWay(int , int);

int main()
{
cin >> rows >> columns ;
for(int i = 0 ; i < rows ; ++i)
{
for(int j = 0 ; j < columns ; ++j)
{
cin >> a[i][j] ;
}
}

//将第一个字符的信息存入到vector
letters.push_back(a[0][0]);
count++ ;
tempR.push_back(0) ;
tempC.push_back(0) ;
tempN.push_back(findWay(0,0)) ;

startGo(0 , 0) ;
cout << maxCount << endl ;
return 0 ;

}

int findWay(int r, int c)
{
int countWay = 0 ;
if(isUp(r , c))
{
p[r][c][0] = true ;
countWay++ ;
}
if(isDown(r , c))
{
p[r][c][1] = true ;
countWay++ ;
}
if(isLeft(r , c))
{
countWay++ ;
p[r][c][2] = true ;
}
if(isRight(r , c))
{
countWay++ ;
p[r][c][3] = true ;
}

return countWay ;
}
/**
*在判断是否往某个方向走时,要将其与当前的letters中的字符进行比较,如果重复不能走
*/
bool isUp(int r , int c)
{
if(r > 0)
{
for(int i = 0 ; i < letters.size() ; ++i)
{
if(a[r-1][c] == letters[i])
{
return false ;
}
}
return true ;
}
else
return false ;
}

bool isDown(int r , int c)
{
if(r < rows-1)
{
for(int i = 0 ; i < letters.size() ; ++i)
{
if(a[r+1][c] == letters[i])
{
return false ;
}
}
return true ;
}
else
return false;
}

bool isLeft(int r , int c)
{
if(c > 0)
{
for(int i = 0 ; i < letters.size() ; ++i)
{
if(a[r][c-1] == letters[i])
{
return false ;
}
}
return true ;
}
return false ;
}

bool isRight(int r , int c)
{
if(c < columns-1)
{
for(int i = 0 ; i < letters.size() ; ++i)
{
if(a[r][c+1] == letters[i])
{
return false ;
}
}
return true ;
}
return false ;
}

void startGo(int r , int c)
{
int wayN = -1 ;
//从所有的路径当中任意选择一条,并将此条路径对应的p中的值设为false,这样下次就不能再走
for(int k = 0 ; k < 4 ; ++k)
{
if(p[r][c][k]==true)
{
wayN = k ;
p[r][c][k] = false ;
//因为已经走了当前字符的某一条路径,因此在原来基础上路径条数减少1
int size = tempN.size()-1 ;
tempN[size] = tempN[size] - 1 ;
//找到一条路径后马上跳出循环,并且沿着这条路径走下去
break ;
}
}
if(wayN == 0)
{
goWay(r-1 , c) ;
}
else if(wayN == 1)
{
goWay(r+1 , c);
}
else if(wayN == 2)
{
goWay(r , c-1);
}
else if(wayN == 3)
{
goWay(r , c+1);
}
/**
*如果说当前的结点已经没有可以走的路径了,那么返回寻找路径条数大于等于1的结点
*并且将结点路径数为0的结点移除,找到路径数大于等于1的结点后就进入走该结点的另一条路径
*/
else if(tempR.size() > 0)
{
if(count > maxCount)
{
maxCount = count ;
}

int s = tempR.size() ;

if(s > 0)
{
for(int m = s-1 ; m >= 0 ; --m)
{
if(tempN[m] < 1)
{
tempR.pop_back();
tempC.pop_back();
tempN.pop_back();

letters.pop_back();
count-- ;
if(tempR.size() ==0)
{
break ;
}
}
else if(tempN[m] >= 1)
{
r = tempR[m] ;
c = tempC[m] ;
startGo(r,c) ;
}
}
}
}
}
//将新走到的结点信息存入
void goWay(int row , int col)
{
r = row ;
c = col ;

letters.push_back(a[r][c]);
count++ ;
tempR.push_back(r) ;
tempC.push_back(c) ;
int wayNumber = findWay(r , c);
tempN.push_back(wayNumber) ;
startGo(r , c) ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: