您的位置:首页 > 其它

棋盘游戏

2017-07-01 18:29 239 查看


Sample Input

3 3 4

1 2

1 3

2 1

2 2

3 3 4

1 2

1 3

2 1

3 2

Sample Output

Board 1 have 0 important blanks for 2 chessmen.

Board 2 have 3 important blanks for 3 chessmen.

//题意:同行、同列中只能有一个棋子,给定一个地图,求该地图中能放的最大棋子数和重要点个数(介绍见思路)。

//思路:匈牙利算法模板题。直接套模板可求最大棋子数。把一个原本可以放棋子的地方(map[][]==1的点)设置成不能放棋子(map[][]==0),若最大棋子数变少了,那么该点为“重要点”。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;

#define MAX 100+10

int n, m, k;
int x[MAX*MAX], y[MAX*MAX];  //存放可以放棋子的点的坐标
int map[MAX][MAX]; //地图
int used[MAX], visit[MAX];

int find(int x)
{
int i;
for (i = 1; i <= m; i++)
{
if (map[x][i] == 1 && visit[i] == 0)
{
visit[i] = 1;
if (used[i] == 0 || find(used[i]) == 1)
{
used[i] = x;
return 1;
}
}
}
return 0;
}

//匈牙利算法(递归实现)
int hungarian()
{
int i, sum = 0;
memset(used, 0, sizeof(used));
for (i = 1; i <= n; i++)
{
memset(visit, 0, sizeof(visit));
if (find(i))
sum++;
}
return sum;
}

int main()
{
int i, tt = 1;
while (~scanf("%d%d%d", &n, &m, &k))
{
memset(map, 0, sizeof(map));
for (i = 1; i <= k; i++)
{
scanf("%d%d", &x[i], &y[i]);
map[x[i]][y[i]] = 1;
}

int ans = hungarian(); //求棋子的最大个数
int sum = 0;

//若把一个原本是1的地方换成0后,最大棋子个数减小,则该点为重要点
for (i = 1; i <= k; i++)
{
map[x[i]][y[i]] = 0;
int num = hungarian();
if (num < ans)
sum++;
map[x[i]][y[i]] = 1;
}

printf("Board %d have %d important blanks for %d chessmen.\n", tt, sum, ans);
tt++;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: