zoukankan      html  css  js  c++  java
  • AcWing 378. 骑士放置 题解

    原题链接

    题目描述

    给定一个 N*M 的棋盘,有一些格子禁止放棋子。

    问棋盘上最多能放多少个不能互相攻击的骑士(国际象棋的“骑士”,类似于中国象棋的“马”,按照“日”字攻击,但没有中国象棋“别马腿”的规则)。

    样例

    输入样例
    2 3 0
    
    输出样例
    4
    

    (二分图——最大独立集) O ( n ∗ m ) O(n*m) O(nm)

    思路:通过涂色法(棋子位置和除棋子可到位置变黑色,其余不变)发现,黑色与白色有公共边,即可使用二分图求解

    时间复杂度

    O ( n ∗ m ) O(n*m) O(nm)

    参考文献

    y总的课+《算法竞赛进阶指南》

    C++ 代码

    #include<bits/stdc++.h>
    #define x first
    #define y second
    using namespace std;
    typedef pair<int,int> PII;
    const int maxn=110;
    PII match[maxn][maxn];
    bool g[maxn][maxn];
    int n,m,t,x,y,res;
    bool st[maxn][maxn];
    int fx[]={-2,-1,1,2,2,1,-1,-2};
    int fy[]={1,2,2,1,-1,-2,-2,-1};
    bool find(int x,int y){
    	for(int i=0;i<8;i++){
    	    int a=x+fx[i];
    	    int b=y+fy[i];
    	    if(a<1||a>n||b<1||b>m)continue;
    	    if(g[a][b]||st[a][b])continue;
    	    st[a][b]=true;
    	    PII t=match[a][b];
    	    if(t.x==0||find(t.x,t.y)){
    	        match[a][b]={x,y};
    	        return true;
    	    }
    	}
    	return false;
    }
    int main(){
        scanf("%d%d%d",&n,&m,&t);
        for(int i=1;i<=t;i++){
            scanf("%d%d",&x,&y);
        	g[x][y]=true;
        }
    	for(int i=1;i<=n;i++){
        	for(int j=1;j<=m;j++){
        	    if((i+j)%2||g[i][j])continue;
        	    memset(st,false,sizeof st);
    			if(find(i,j)){
    				res++;
    			}
    		}
    	}
    	cout<<n*m-res-t;
        return 0;
    }
    
    她透过我的血,看到了另一抹殷红
  • 相关阅读:
    SQl语句学习笔记(二)
    Adaboost 算法
    降维PCA技术
    scanf 格式化字符串详解
    大小端模式和位域详解(转载)
    推荐系统开源软件列表汇总和点评(转载)
    遗传算法入门(转载)
    大白话解析模拟退火算法(转载)
    机器学习相关——协同过滤(转载)
    python面向对象之单例模式
  • 原文地址:https://www.cnblogs.com/zhangbeini/p/13771257.html
Copyright © 2011-2022 走看看