【SSLGZ 1344】Knights
2017-06-28 11:36
701 查看
问题描述
We are given a chess-board of size n*n, from which some fields have been removed. The task is to determine the maximum number of knights that can be placed on the remaining fields of the board in such a way that none of them check each other.
一张大小为n*n的国际象棋棋盘,上面有一些格子被拿走了,棋盘规模n不超过200。马的攻击方向如下图,其中S处为马位置,标有X的点为该马的攻击点。
Fig.1: A knight placed on the field S checks fields marked with x.
Write a program, that:
reads the description of a chess-board with some fields removed, from the input file kni.in,
determines the maximum number of knights that can be placed on the chess-board in such a way that none of them check each other,
writes the result to the output file kni.out.
你的任务是确定在这个棋盘上放置尽可能多的马,并使他们不互相攻击。
输入
The first line of the input file kni.in contains two integers n and m, separated by a single space, 1<=n<=200, 0<=m<n2; n is the chess-board size and m is the number of removed fields. Each of the following m lines contains two integers: x and y, separated by a single space, 1<=x,y<=n – these are the coordinates of the removed fields. The coordinates of the upper left corner of the board are (1,1), and of the bottom right are (n,n). The removed fields are not repeated in the file.
n*n的棋盘,有m个点不能放置骑士
之后m行为不得放置骑士的坐标
输出
The output file kni.out should contain one integer (in the first and only line of the file). It should be the maximum number of knights that can be placed on the given chess-board without checking each other.
样例输入
3 2
1 1
3 3
样例输出
5
算法讨论
这里的方法有点慢,把能放置骑士的点枚举,将它所能攻击的点标号,连接起来,然后用匹配做一遍最大覆盖集,将总点数减去最大覆盖集的点数就是我们求的答案。
Pixiv ID:46661498
We are given a chess-board of size n*n, from which some fields have been removed. The task is to determine the maximum number of knights that can be placed on the remaining fields of the board in such a way that none of them check each other.
一张大小为n*n的国际象棋棋盘,上面有一些格子被拿走了,棋盘规模n不超过200。马的攻击方向如下图,其中S处为马位置,标有X的点为该马的攻击点。
Fig.1: A knight placed on the field S checks fields marked with x.
Write a program, that:
reads the description of a chess-board with some fields removed, from the input file kni.in,
determines the maximum number of knights that can be placed on the chess-board in such a way that none of them check each other,
writes the result to the output file kni.out.
你的任务是确定在这个棋盘上放置尽可能多的马,并使他们不互相攻击。
输入
The first line of the input file kni.in contains two integers n and m, separated by a single space, 1<=n<=200, 0<=m<n2; n is the chess-board size and m is the number of removed fields. Each of the following m lines contains two integers: x and y, separated by a single space, 1<=x,y<=n – these are the coordinates of the removed fields. The coordinates of the upper left corner of the board are (1,1), and of the bottom right are (n,n). The removed fields are not repeated in the file.
n*n的棋盘,有m个点不能放置骑士
之后m行为不得放置骑士的坐标
输出
The output file kni.out should contain one integer (in the first and only line of the file). It should be the maximum number of knights that can be placed on the given chess-board without checking each other.
样例输入
3 2
1 1
3 3
样例输出
5
算法讨论
这里的方法有点慢,把能放置骑士的点枚举,将它所能攻击的点标号,连接起来,然后用匹配做一遍最大覆盖集,将总点数减去最大覆盖集的点数就是我们求的答案。
#include<cstdio> #include<cstring> using namespace std; int dx[9]={0,-1,-2,-2,-1,1,2,2,1}; int dy[9]={0,-2,-1,1,2,2,1,-1,-2}; int a[40005][9]; bool f[405][405]; int num[405][405]; bool v[40005]; int link[40005]; int n,m,s,ans; bool check(int x,int y) { if (x<1||x>n||y<1||y>n) return false; if (f[x][y]) return false; return true; } bool find(int x) { int p; for (int i=1;i<=a[x][0];i++) if (v[a[x][i]]==false) { p=link[a[x][i]]; link[a[x][i]]=x; v[a[x][i]]=true; if ((p==0)||(find(p))) return true; link[a[x][i]]=p; } return false; } int main() { scanf("%d%d",&n,&m); int x,y; for (int i=1;i<=m;i++) { scanf("%d%d",&x,&y); f[x][y]=true; } s=0; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (f[i][j]==false) { s++; num[i][j]=s; } int p=0; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (f[i][j]==false) { p=num[i][j]; int t=0; for (int k=1;k<=8;k++) { x=i+dx[k]; y=j+dy[k]; if (check(x,y)) { t++; a[p][t]=num[x][y]; } } a[p][0]=t; } for (int i=1;i<=s;i++) { if (a[i][0]==0) continue; memset(v,0,sizeof(v)); if (find(i)) ans++; } ans=ans/2; printf("%d",s-ans); return 0; }
Pixiv ID:46661498
相关文章推荐
- POJ2942-Knights of the Round Table
- UVa10422 - Knights in FEN
- UVa 696 - How Many Knights
- UVa1344 - Tian Ji -- The Horse Racing
- POJ 2942 Knights of the Round Table 点全连通分量 + DFS染色 做的好辛苦
- hdu4337 King Arthur's Knights(dfs回溯)
- uva 696 - How Many Knights
- uva 1344
- POJ 2942 Knights of the Round Table 黑白着色+点双连通分量
- UVA - 10422 Knights in FEN(bfs+hash)
- 【vijos】1729 Knights(匈牙利)
- UVa 10422 - Knights in FE
- 贪心/数学 Codeforces Round #212 (Div. 2) A. Two Semiknights Meet
- UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
- sicily 1172. Queens, Knights and Pawns
- 51nod 1344 走格子
- LightOJ 1010 Knights in Chessboard
- USTC 1344
- HDU 5819 Knights(概率DP)
- 【codeforces】gym 101137 K - Knights of the Old Republic【用最小生成树对图做集合dp】