Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
悲剧啊,花了将近2小时。。。。回溯法清晰解决。理论上应该可以解决N较大的问题。不过回溯所有点。故效率不高。 #include <iostream> #define N 10 using namespace std; char map[N*N]; int visit[N*N]; int a[N*N]; bool can_visit(int i,int n) { int x,j; x = i/n; if( visit[i] != 0 ) return false; for ( j = i-1 ; j >= n*x ; j--) { if( visit[j] == 2 ) break; if( visit[j] == 1 ) return false; } for ( j = i-n ; j >= 0 ; j=j-n) { if( visit[j] == 2 ) break; if( visit[j] == 1 ) return false; } return true; } int next(int i,int n) { //从点i起,寻找下一个可走的点 for(int j = i ; j < n*n ; j++) { if(can_visit(j,n)) return j; } return -1; } int back(int n) { int i,j,count,max; memset(visit,0,sizeof(visit)); memset(a,0,sizeof(a)); for ( i = 0 ; i < n ; i++) { for ( j = 0 ; j < n ; j++) { cin>>map[i*n+j]; if( map[i*n+j] == 'X' ) visit[i*n+j] = 2 ; //else visit[i*n+j] = 2 ; //cout<<visit[i*n+j]<<" "; } //cout<<endl; } max = 0 ; count = 0 ; //回溯求解 while (1) { if( count > 0 ) { i = next(a[count-1]+1,n) ; if( i == -1 ) { //之后的点都不满足,即该回溯了。 if( count > max ) max = count; //回溯,先查看去掉count点后是否还有可用之点。 visit[a[count-1]] = 0 ; //标记 i = next(a[count-1]+1,n) ; while( i == -1 ) { if( count == 1 ) return max; count--; visit[a[count-1]] = 0 ; //标记 i = next(a[count-1]+1,n) ; } visit[i] = 1; a[count-1] = i ; } else { //之后还有点,故向前 a[count++] = i ; visit[i] = 1 ; } } else { i = next(0,n); if( i == -1 ) return 0; visit[i] = 1 ; a[count++] = i ; } } } int main() { int n;//,res; cin>>n; while (n!=0) { //res = back(n); cout<<back(n)<<endl; cin>>n; } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator