SGU 125 Shtirlits 搜索+可行性剪枝
2013-07-25 20:42
281 查看
500ms时限406ms水过……
直接枚举肯定超时,需要剪枝。
枚举每个格子的元素,检查其左上角和正上方格子是否满足条件,若不满足不必再向下搜索。
在 这里 看到一个更好的方法: 枚举每个格子是哪个相邻的比它大。然后DFS看看有没有环。这样的复杂度只有(2^5*3^5)。
不过我没写出来……而且也不太清楚这个时间复杂度是怎么算的……求指点!
直接枚举肯定超时,需要剪枝。
枚举每个格子的元素,检查其左上角和正上方格子是否满足条件,若不满足不必再向下搜索。
在 这里 看到一个更好的方法: 枚举每个格子是哪个相邻的比它大。然后DFS看看有没有环。这样的复杂度只有(2^5*3^5)。
不过我没写出来……而且也不太清楚这个时间复杂度是怎么算的……求指点!
#include <cstdio> #include <cstring> #include <cstdlib> const int dx[] = { -1, 1, 0, 0 }; const int dy[] = { 0, 0, -1, 1 }; int N; int mat[5][5]; int G[5][5]; bool check( int i, int j ) { return i >= 0 && i < N && j >= 0 && j < N; } //wh=true 代表检查左上角格子是否满足条件, wh=false代表检查正上方格子 bool ok( int x, int y, bool wh ) { int cnt = 0; for ( int k = 0; k < 4; ++k ) { int xx = x + dx[k]; int yy = y + dy[k]; if ( check( xx, yy ) && G[xx][yy] > G[x][y] ) ++cnt; } if ( wh ) return cnt == mat[x][y]; return cnt <= mat[x][y]; } bool Judge() { int cnt = 0; for ( int i = 0; i < N; ++i ) { for ( int j = 0; j < N; ++j ) { cnt = 0; for ( int k = 0; k < 4; ++k ) { int xx = i + dx[k]; int yy = j + dy[k]; if ( check( xx, yy ) ) { if ( G[xx][yy] > G[i][j] ) ++cnt; } } if ( cnt != mat[i][j] ) return false; } } return true; } bool DFS( int cur ) { if ( cur == N * N ) { if ( Judge() ) return true; return false; } int x = cur / N; int y = cur % N; for ( int i = 0; i < 10; ++i ) { G[x][y] = i; bool okey = true; if ( check( x - 1, y - 1 ) ) { if ( !ok( x - 1, y - 1, true ) ) okey = false; } if ( okey && check( x - 1, y ) ) { if ( !ok( x - 1, y, false ) ) okey = false; } if ( okey ) { if ( DFS( cur + 1 ) ) return true; } G[x][y] = -1; } return false; } int main() { //freopen( "s.out", "w", stdout ); while ( scanf( "%d", &N ) == 1 ) { for( int i = 0; i < N; ++i ) for( int j = 0; j < N; ++j ) scanf( "%d", &mat[i][j] ); memset( G, -1, sizeof( G ) ); if ( DFS( 0 ) ) { for ( int i = 0; i < N; ++i ) { for ( int j = 0; j < N; ++j ) { if ( j ) putchar(' '); printf( "%d", G[i][j] ); } puts(""); } } else puts("NO SOLUTION"); } return 0; }
相关文章推荐
- Shtirlits - SGU 125(搜索)
- Shtirlits - SGU 125 dfs
- SGU 125 Shtirlits
- sgu 125 Shtirlits
- hdu 4090(搜索+可行性剪枝)
- SGU 125 Shtirlits(dfs)
- 浅谈"对抗搜索"的alpha-beta 剪枝
- POJ 1568 Find the Winning Move 极大极小搜索+alpha-beta剪枝 -
- 搜索+剪枝——运筹帷幄 (road.cpp)
- UVA 529 - Addition Chains,迭代加深搜索+剪枝
- 搜索与剪枝
- [NOIP模拟题][Catalan数][逆元][贪心][线段树][DFS][搜索顺序剪枝]
- Tempter of the Bone 搜索---奇偶性剪枝
- Network Saboteur POJ - 2531 暴力搜索+剪枝技巧
- HDU 5235 Friends (2015 Multi-University Training Contest 2 搜索+剪枝)
- Network Saboteur poj 2531 dfs 简单搜索技巧和剪枝
- Biggest Number(刘汝佳,搜索+剪枝)
- *搜索(剪剪剪枝)POJ - 1011 Sticks
- UVALive 4527 Vaccination Centers 搜索+剪枝
- poj 1011 Sticks(经典搜索问题:DFS+剪枝)