题意:已知一个n*m的中国象棋棋盘,上面有k个棋子,要在棋盘上摆尽可能多的炮,并且任意两个炮不能互相攻击,求该棋盘最多能摆多少个炮
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4499
思路:n皇后问题的变种,dfs+回溯就行,注意判断不要在一格内重复放棋子。
注意点:思路感觉没有问题,搜索的过程也感觉没问题,样例和自己想的数据也过了,可是一直A不掉,借了bin神的代码来随机生成数据对拍,终于发下问题了,最右下角的点没处理好,一直处于搜不到的状态(到现在还不知道怎么改),参考了bin神的代码之后Ac了。
以下为AC代码:
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
12474299 | 2014-12-12 08:55:57 | Accepted | 4499 | 62MS | 1216K | 2561 B | G++ | luminous11 |
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <deque>
#include <list>
#include <cctype>
#include <algorithm>
#include <climits>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#define ll long long
#define ull unsigned long long
#define all(x) (x).begin(), (x).end()
#define clr(a, v) memset( a , v , sizeof(a) )
#define pb push_back
#define mp make_pair
#define read(f) freopen(f, "r", stdin)
#define write(f) freopen(f, "w", stdout)
using namespace std;
struct node
{
int x;
int y;
};
int adj[50][50];
int m, n, k;
int maxn;
void dfs ( int x, int y, int cnt )
{
if ( x >= n )
{
maxn = max ( maxn, cnt );
return;
}
if ( y >= n )
{
dfs ( x + 1, 0, cnt );
return;
}
if ( adj[x][y] == 1 )
{
dfs ( x, y + 1, cnt );
return;
}
dfs ( x, y + 1, cnt );
bool flag = false;
int t;
for ( int i = x - 1; i >= 0; i -- )
{
if ( adj[i][y] )
{
if ( flag == false )
{
flag = true;
continue;
}
else
{
if ( adj[i][y] == 2 )
{
return;
}
else
{
break;
}
}
}
}
flag = false;
for ( int i = y - 1; i >= 0; i -- )
{
if ( adj[x][i] )
{
if ( flag == false )
{
flag = true;
continue;
}
else
{
if ( adj[x][i] == 2 )
{
return;
}
else
{
break;
}
}
}
}
adj[x][y] = 2;
dfs ( x, y + 1, cnt + 1 );
adj[x][y] = 0;
}
int main()
{
while ( cin >> n >> m >> k )
{
struct node p[50];
maxn = 0;
memset ( p, 0, sizeof ( p ) );
memset ( adj, 0, sizeof ( adj ) );
for ( int i = 0; i < k; i ++ )
{
cin >> p[i].x >> p[i].y;
adj[p[i].x][p[i].y] = 1;
}
dfs ( 0, 0, 0 );
cout << maxn << endl;
}
return 0;
}
在最后放出原来的错误的代码。
欢迎各位大神批评指正。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <deque>
#include <list>
#include <cctype>
#include <algorithm>
#include <climits>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#define ll long long
#define ull unsigned long long
#define all(x) (x).begin(), (x).end()
#define clr(a, v) memset( a , v , sizeof(a) )
#define pb push_back
#define mp make_pair
#define read(f) freopen(f, "r", stdin)
#define write(f) freopen(f, "w", stdout)
using namespace std;
struct node
{
int x;
int y;
};
int adj[50][50];
int m, n, k;
int maxn;
int check ( int x, int y )
{
int flag = 0;
for ( int i = x - 1; i >= 0; i -- )
{
if ( flag == 0 && adj[i][y] )
{
flag = 1;
continue;
}
else if ( flag == 1 && adj[i][y] == 1 )
{
flag = 0;
break;
}
else if ( flag == 1 && adj[i][y] == 2 )
{
return 0;
}
}
flag = 0;
for ( int i = y - 1; i >= 0; i -- )
{
if ( flag == 0 && adj[x][i] )
{
flag = 1;
continue;
}
else if ( flag == 1 && adj[x][i] == 1 )
{
flag = 0;
break;
}
else if ( flag == 1 && adj[x][i] == 2 )
{
return 0;
}
}
return 1;
}
void dfs ( int x, int y, int cnt )
{
if ( maxn < cnt )
{
maxn = cnt;
}
if ( adj[x][y] == 1 )
{
if ( y < m - 1 )
{
dfs ( x + 1, 0, cnt );
}
if ( x < n - 1 )
{
dfs ( x, y + 1, cnt );
}
return;
}
if ( y < m - 1 )
{
dfs ( x, y + 1, cnt );
}
else if ( x < n - 1 )
{
dfs ( x + 1, 0, cnt );
}
if ( check ( x, y ) )
{
if ( y < m - 1 )
{
adj[x][y] = 2;
dfs ( x, y + 1, cnt + 1 );
adj[x][y] = 0;
}
else if ( x < n - 1 )
{
adj[x][y] = 2;
dfs ( x + 1, 0, cnt + 1 );
adj[x][y] = 0;
}
return;
}
return;
}
int main()
{
while ( cin >> n >> m >> k )
{
struct node p[50];
maxn = 0;
memset ( p, 0, sizeof ( p ) );
memset ( adj, 0, sizeof ( adj ) );
for ( int i = 0; i < k; i ++ )
{
cin >> p[i].x >> p[i].y;
adj[p[i].x][p[i].y] = 1;
}
dfs ( 0, 0, 0 );
cout << maxn << endl;
}
return 0;
}