zoukankan      html  css  js  c++  java
  • CODEVS 2171 棋盘覆盖

    2171 棋盘覆盖

    给出一张nn(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少12的多米诺骨牌进行掩盖。


    错误日志: 直接在模板上调整 (maxn) 时没有在相应邻接表数组位置把数组大小调整为 (maxn * maxn)


    Solution

    经典的二分图匹配问题
    (1) 要素: 每个点只能被一张骨牌覆盖
    (0) 要素: 将棋盘黑白染色, 其对角线格子不可能被一张骨牌覆盖
    染色方法: (if(i + j) \% 2 == 0) 染为白色

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    #define REP(i, x, y) for(int i = (x);i <= (y);i++)
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = 419, maxv = 1000019, INF = 1e9 + 19;
    int head[maxn * maxn],nume = 1;
    struct Node{
        int v,dis,nxt;
        }E[maxv << 3];
    void add(int u,int v,int dis){
        E[++nume].nxt = head[u];
        E[nume].v = v;
        E[nume].dis = dis;
        head[u] = nume;
        }
    int len, num;
    int map[maxn][maxn];
    int mx[4] = {1,-1, 0, 0};
    int my[4] = {0, 0, 1,-1};
    bool judge(int x, int y){
    	if(x < 1 || x > len || y < 1 || y > len)return 0;
    	return 1;
    	}
    int id(int x, int y){return (x - 1) * len + y;}
    int mat[maxn * maxn], used[maxn * maxn];
    bool match(int u){
    	for(int i = head[u];i;i = E[i].nxt){
    		int v = E[i].v;
    		if(!used[v]){
    			used[v] = 1;
    			if(!mat[v] || match(mat[v])){
    				mat[v] = u;
    				return 1;
    				}
    			}
    		}
    	return 0;
    	}
    int main(){
    	len = RD(), num = RD();
    	REP(i, 1, num){
    		int x = RD(), y = RD();
    		map[x][y] = 1;
    		}
    	REP(i, 1, len)REP(j ,1, len){
    		if((i + j) % 2 == 1 || map[i][j])continue;
    		int u = id(i ,j);
    		for(int k = 0;k < 4;k++){
    			int nx = i + mx[k];
    			int ny = j + my[k];
    			if(!judge(nx, ny))continue;
    			if(map[nx][ny])continue;
    			int v = id(nx, ny);
    			add(u, v, 1);
    			}
    		}
    	int ans = 0;
    	REP(i, 1, len)REP(j, 1, len){
    		if((i + j) % 2 == 1 || map[i][j])continue;
    		memset(used, 0, sizeof(used));
    		if(match(id(i, j)))ans++;
    		}
    	printf("%d
    ", ans);
    	return 0;
    	}
    
  • 相关阅读:
    最短路径—Dijkstra算法和Floyd算法
    设计模式之工厂模式(Factory模式)
    接口继承与实现继承
    设计模式之工厂模式
    C++的四种强制转型形式:
    手写atoi、strcpy、strcat
    进程和线程关系及区别
    海量数据处理
    什么是死锁,简述死锁发生的四个必要条件,如何避免与预防死锁
    kolla-ansible 重新部署 ceph 遇到的问题
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9755350.html
Copyright © 2011-2022 走看看