zoukankan      html  css  js  c++  java
  • CH6802 車的放置 和 CH6B24 Place the Robots

    描述

    给定一个N行M列的棋盘,已知某些格子禁止放置。问棋盘上最多能放多少个不能互相攻击的車。車放在格子里,攻击范围与中国象棋的“車”一致。N,M≤200。

    输入格式

    第一行为n,m,t(表示有t个禁止的格子)
    第二行到t+1行为x,y,分别表示禁止格子所在的位置,x为第x行,y为第y列,行列编号从1开始。 

    输出格式

    一个整数,表示最多能放多少个車。

    样例输入

    8 8 0

    样例输出

    8
            </article>
    

    题解

    把行、列看成节点
    1要素:行节点、列节点只能放一个
    0要素:行节点之间没有边,列节点之间也没有
    所以建二分图跑最大匹配,时间复杂度(O((n+m)nm))

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read(){
        rg T data=0,w=1;rg char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
        for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
        return data*w;
    }
    template<class T>il T read(rg T&x) {return x=read<T>();}
    typedef long long ll;
    
    co int N=201;
    int n,m,t,ans,fa[N];
    bool a[N][N],v[N];
    bool dfs(int x){
    	for(int y=1;y<=m;++y){
    		if(a[x][y]||v[y]) continue;
    		v[y]=1;
    		if(!fa[y]||dfs(fa[y])){
    			fa[y]=x;
    			return 1;
    		}
    	}
    	return 0;
    }
    int main(){
    	read(n),read(m),read(t);
    	while(t--) a[read<int>()][read<int>()]=1;
    	for(int i=1;i<=n;++i){
    		memset(v,0,sizeof v);
    		ans+=dfs(i);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    描述

    给出一个地图(网格),格子分为空地,草地,墙壁。要在空地上放能向上下左右4个方向发射激光的机器人。墙壁能挡住激光,草地不能挡住激光也不能放机器人。问最多能放多少个,使得机器人不能对打。

    Robert is a famous engineer. One day he was given a task by his boss. The background of the task was the following:

    Given a map consisting of square blocks. There were three kinds of blocks: Wall, Grass, and Empty. His boss wanted to place as many robots as possible in the map. Each robot held a laser weapon which could shoot to four directions (north, east, south, west) simultaneously. A robot had to stay at the block where it was initially placed all the time and to keep firing all the time. The laser beams certainly could pass the grid of Grass, but could not pass the grid of Wall. A robot could only be placed in an Empty block. Surely the boss would not want to see one robot hurting another. In other words, two robots must not be placed in one line (horizontally or vertically) unless there is a Wall between them.

    Now that you are such a smart programmer and one of Robert's best friends, He is asking you to help him solving this problem. That is, given the description of a map, compute the maximum number of robots that can be placed in the map.

    输入格式

    The first line contains an integer T (<= 11) which is the number of test cases. 

    For each test case, the first line contains two integers m and n (1<= m, n <=50) which are the row and column sizes of the map. Then m lines follow, each contains n characters of '#', '*', or 'o' which represent Wall, Grass, and Empty, respectively.

    输出格式

    For each test case, first output the case number in one line, in the format: "Case :id" where id is the test case number, counting from 1. In the second line just output the maximum number of robots that can be placed in that map.

    样例输入

    2
    4 4
    o***
    *###
    oo#o
    ***o
    4 4
    #ooo
    o#oo
    oo#o
    ***#

    样例输出

    Case :1
    3
    Case :2
    5

    来源

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1654

            </article>
    

    题解

    几乎就是每行每列只能放一个。现在有了墙壁,相当于多拆出来一些点。并且墙壁和草地让连边少了一点。

    时间复杂度(O(n^3))

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read(){
        rg T data=0,w=1;rg char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
        for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
        return data*w;
    }
    template<class T>il T read(rg T&x) {return x=read<T>();}
    typedef long long ll;
    using namespace std;
    
    co int N=51;
    int n,m,fa[N][N],fb[N][N],f[N*N],id;
    char s[N][N];
    vector<int> e[N*N];
    bitset<N*N> v;
    il void add(int x,int y){
    	e[x].push_back(y);
    }
    bool dfs(int x){
    	for(unsigned i=0;i<e[x].size();++i){
    		int y=e[x][i];
    		if(v[y]) continue;
    		v[y]=1;
    		if(!f[y]||dfs(f[y])){
    			f[y]=x;
    			return 1;
    		}
    	}
    	return 0;
    }
    void Place_the_Robots(){
    	read(n),read(m);
    	for(int i=1;i<=n;++i) scanf("%s",s[i]+1);
    	int a=0;
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=m;++j)if(s[i][j]!='#')
    			fa[i][j]=a+=j==1||s[i][j-1]=='#';
    	int b=a;
    	for(int j=1;j<=m;++j)
    		for(int i=1;i<=n;++i)if(s[i][j]!='#')
    			fb[i][j]=b+=i==1||s[i-1][j]=='#';
    	for(int i=1;i<=b;++i) e[i].clear(),f[i]=0;
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=m;++j)if(s[i][j]=='o')
    			add(fa[i][j],fb[i][j]),add(fb[i][j],fa[i][j]);
    	int ans=0;
    	for(int i=1;i<=a;++i){
    		v<<=b;
    		ans+=dfs(i);
    	}
    	printf("Case :%d
    %d
    ",++id,ans);
    }
    int main(){
    	for(int t=read<int>();t--;) Place_the_Robots();
    	return 0;
    }
    
  • 相关阅读:
    bzoj 1026
    mysql索引面试题
    Mybatis基础,动态sql (mybatis中的重点)
    Mybatis基础,利用mybatis实现复杂查询,多对一,一对多
    Mybatis基础:注解开发,面向接口(引出三个面向的区别)
    Mybatis基础,limit分页,和RowsBounds分页,分页插件
    Mybatis基础,日志工厂
    Mybatis基础一,生命周期,和作用域,resultMap(结果集映射)
    Mybatis配置解析三,typeAliases(别名),setting(设置)
    浅谈JPA
  • 原文地址:https://www.cnblogs.com/autoint/p/10971406.html
Copyright © 2011-2022 走看看