500ms时限406ms水过……
直接枚举肯定超时,需要剪枝。
枚举每个格子的元素,检查其左上角和正上方格子是否满足条件,若不满足不必再向下搜索。
在 这里 看到一个更好的方法: 枚举每个格子是哪个相邻的比它大。然后DFS看看有没有环。这样的复杂度只有(2^5*3^5)。
不过我没写出来……而且也不太清楚这个时间复杂度是怎么算的……求指点!
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 const int dx[] = { -1, 1, 0, 0 }; 6 const int dy[] = { 0, 0, -1, 1 }; 7 8 int N; 9 int mat[5][5]; 10 int G[5][5]; 11 12 bool check( int i, int j ) 13 { 14 return i >= 0 && i < N && j >= 0 && j < N; 15 } 16 17 //wh=true 代表检查左上角格子是否满足条件, wh=false代表检查正上方格子 18 bool ok( int x, int y, bool wh ) 19 { 20 int cnt = 0; 21 for ( int k = 0; k < 4; ++k ) 22 { 23 int xx = x + dx[k]; 24 int yy = y + dy[k]; 25 if ( check( xx, yy ) && G[xx][yy] > G[x][y] ) ++cnt; 26 } 27 28 if ( wh ) return cnt == mat[x][y]; 29 return cnt <= mat[x][y]; 30 } 31 32 bool Judge() 33 { 34 int cnt = 0; 35 36 for ( int i = 0; i < N; ++i ) 37 { 38 for ( int j = 0; j < N; ++j ) 39 { 40 cnt = 0; 41 for ( int k = 0; k < 4; ++k ) 42 { 43 int xx = i + dx[k]; 44 int yy = j + dy[k]; 45 if ( check( xx, yy ) ) 46 { 47 if ( G[xx][yy] > G[i][j] ) 48 ++cnt; 49 } 50 } 51 if ( cnt != mat[i][j] ) return false; 52 } 53 } 54 55 return true; 56 } 57 58 bool DFS( int cur ) 59 { 60 if ( cur == N * N ) 61 { 62 if ( Judge() ) return true; 63 return false; 64 } 65 66 int x = cur / N; 67 int y = cur % N; 68 for ( int i = 0; i < 10; ++i ) 69 { 70 G[x][y] = i; 71 72 bool okey = true; 73 74 if ( check( x - 1, y - 1 ) ) 75 { 76 if ( !ok( x - 1, y - 1, true ) ) 77 okey = false; 78 } 79 80 if ( okey && check( x - 1, y ) ) 81 { 82 if ( !ok( x - 1, y, false ) ) 83 okey = false; 84 } 85 86 if ( okey ) 87 { 88 if ( DFS( cur + 1 ) ) 89 return true; 90 } 91 92 G[x][y] = -1; 93 } 94 95 return false; 96 } 97 98 int main() 99 { 100 //freopen( "s.out", "w", stdout ); 101 while ( scanf( "%d", &N ) == 1 ) 102 { 103 for( int i = 0; i < N; ++i ) 104 for( int j = 0; j < N; ++j ) 105 scanf( "%d", &mat[i][j] ); 106 107 memset( G, -1, sizeof( G ) ); 108 if ( DFS( 0 ) ) 109 { 110 for ( int i = 0; i < N; ++i ) 111 { 112 for ( int j = 0; j < N; ++j ) 113 { 114 if ( j ) putchar(' '); 115 printf( "%d", G[i][j] ); 116 } 117 puts(""); 118 } 119 } 120 else puts("NO SOLUTION"); 121 } 122 return 0; 123 }