zoukankan      html  css  js  c++  java
  • Knights

    Description

    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.
    你的任务是确定在这个棋盘上放置尽可能多的马,并使他们不互相攻击。

    Input

    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.

    Output

    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.

    Sample Input

    3 2
    1 1
    3 3

    Sample Output

    5

    .
    .
    .
    .
    .
    .
    分析
    考虑对棋盘进行黑白染色。具体来说,设某个点的位置是i行j列,
    那么当[(i+j)%2==0]时,该点为黑色,否则该点为白色。

    一个很显然的性质,相互攻击的两个位置颜色一定不同。我们把黑点
    放在左边,白点放在右边,那么这个图一定是二分图。
    在这里插入图片描述
    首先我们把点进行编号。设格子有n行m列,第i行j列的格子被编号为
    (i-1)*n+j。而对于被拿走的格子,我们完全可以认为这些点不存在,
    不做任何处理。

    ans=顶点数-拿去的格子-最大匹配

    .
    .
    .
    .
    .
    程序:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n1=0,n,m,ans=0,a[210][210],link[40010],v[50000],head[200000],tj=0;
    int b[40000];
    
    struct node
    {
    	int to,next;
    }f[200000];
    
    
    bool check(int x,int y)
    {
    	if (x<=0||y<=0||x>n||y>n) return false;
    	if ((x+y)%2==0) return false;
    	if (a[x][y]==-1||a[x][y]==0) return false;
    	return true;
    }
    
    void add(int x,int y)
    {
    	f[++tj].next=head[x];
    	f[tj].to=y;
    	head[x]=tj;
    }
    
    void work(int i,int j)
    {
    	int x,y;
    	x=i-2;y=j-1;
    	if (check(x,y)==true) add(a[i][j],a[x][y]);
    	x=i-2;y=j+1;
    	if (check(x,y)==true) add(a[i][j],a[x][y]);
    	x=i-1;y=j-2;
    	if (check(x,y)==true) add(a[i][j],a[x][y]);
    	x=i-1;y=j+2;
    	if (check(x,y)==true) add(a[i][j],a[x][y]);
    	x=i+1;y=j-2;
    	if (check(x,y)==true) add(a[i][j],a[x][y]);
    	x=i+2;y=j-1;
    	if (check(x,y)==true) add(a[i][j],a[x][y]);
    	x=i+1;y=j+2;
    	if (check(x,y)==true) add(a[i][j],a[x][y]);
    	x=i+2;y=j+1;
    	if (check(x,y)==true) add(a[i][j],a[x][y]);
    }
    
    
    int find(int x)
    {
    	for (int i=head[x];i;i=f[i].next)
    	{
    		int j=f[i].to;
    		if (!v[j])
    		{
    			int q=link[j];
    		    link[j]=x;
    		    v[j]=1;
    		    if (!q||find(q)) return 1;
    		    link[j]=q;
    		}
    	}
    	return 0;
    }
    
    int main()
    {
    
    	scanf("%d%d",&n,&m);
    	memset(a,0,sizeof(a));
    	memset(b,0,sizeof(b));
    	
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    		{
    			a[i][j]=(i-1)*n+j;
    			if ((i+j)%2==0) 
    			{
    				n1++;
    				b[n1]=a[i][j];
    			}
    		}
    	
    	for (int i=1;i<=m;i++)
    	{
    		int x,y;
    		scanf("%d%d",&x,&y);
    		a[x][y]=-1;
    	}
    	
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    			if (a[i][j]!=-1&&(i+j)%2==0) work(i,j);
    	
    	for (int i=1;i<=n1;i++)
    	{
    		memset(v,0,sizeof(v));
    		ans+=find(b[i]);
    	}
    	int w=n*n-m-ans;
    	printf("%d",w);
    	
    	return 0;
    }
    
  • 相关阅读:
    [MFC]CImageList仅显示黑色的问题
    [hessdroid]Android下使用Hessian与Java服务端通讯的传值测试
    [MFC]Sqlite问题小记
    [MFC] FTP 遍历服务器目录文件卡住的问题
    ExtJs 备忘录(9)—— Ext常用属性、方法小结 [系列完]
    [MFC]托盘图标删除后不自动消失的问题
    RIL接听电话没有声音的问题 [ RIL_Answer | RIL_SetAudioDevices ]
    [Qt]Qt Creator汉化方法
    [C++]遍历可变参数 (va_list)
    [杀毒]删除U盘autorun.inf
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/10292800.html
Copyright © 2011-2022 走看看