zoukankan      html  css  js  c++  java
  • [洛谷P2124] 奶牛美容

    洛谷题目链接:奶牛美容


    ## 题目描述

    输入输出格式

    输入格式:

    输出格式:

    输入输出样例

    输入样例#1:

    6 16
    ................
    ..XXXX....XXX...
    ...XXXX....XX...
    .XXXX......XXX..
    ........XXXXX...
    ..XXX....XXX....

    输出样例#1:

    4

    简述一下题意:给出一个矩阵,矩阵上有三个点(??),要求出最少改变几个点才能使这三个点变成一个点.


    显然我们可以求出每两个点的距离,答案就是另外两个点到这个点的距离之和.


    然而这样是有问题的,比如这样:

    ...X.....X...
    .............
    ......X......
    

    这样这些点并不需要到连同一个点,所以在之前答案的基础上再枚举一遍三个点到同一个位置的距离之和能不能更新答案就好了.


    步骤:

    1. 广搜求出每个位置所属的点.
    2. 深搜求出一个点到每个位置的最短长度.
    3. 对到同一点和三点再外面连通的情况取最小值.
    4. 最后答案要-2(因为在计算距离时是算的连入到一个点的长度,所以连进去的那个格子不要算).

    #include<bits/stdc++.h>
    using namespace std;
    const int N=500+5;
    const int inf=2147483647;
    
    int n, m, cnt = 0, ans = inf;
    char a[N][N];
    int col[N][N];
    int mn[N][N];
    int d[4][N][N];
    int mv[]={1,0,-1,0,1};
    
    struct node{
        int x, y;
    };
    
    bool ok(node nt){
        if(nt.x < 1 || nt.x > n) return false;
        if(nt.y < 1 || nt.y > m) return false;
        if(col[nt.x][nt.y] || a[nt.x][nt.y] != 'X') return false;
        return true;
    }
    
    void bfs(int x,int y){
    	cnt++; queue <node> q;
    	q.push((node){x,y}); col[x][y] = cnt;
    	node now, nt;
        while(!q.empty()){
    	    now = q.front(); q.pop();
    	    for(int i=0;i<4;i++){
    	        nt.x = now.x+mv[i]; nt.y = now.y+mv[i+1];
    	        if(ok(nt)) col[nt.x][nt.y] = cnt, q.push(nt);
    	    }
        }
    }
    
    void dfs(int color,int x,int y,int step){
        if(d[color][x][y] <= step) return;
        d[color][x][y] = step;
        int nx, ny;
        for(int i=0;i<4;i++){
    	    nx = x+mv[i], ny = y+mv[i+1];
    	    if(nx>=1 && nx<=n && ny>=1 && ny<=m)
    	        dfs(color,nx,ny,step+1);
        }
    }
    
    int main(){
        //freopen("war.in","r",stdin);
        //freopen("war.out","w",stdout);
        char ch; cin >> n >> m;
        for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++)
    	        cin >> a[i][j];
        for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++)
    	        if(!col[i][j] && a[i][j] == 'X') bfs(i,j);
        memset(d,127/3,sizeof(d));
        for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++)
    	        if(a[i][j] == 'X') dfs(col[i][j],i,j,0);
    	    memset(mn,127/3,sizeof(mn));
    	for(int c=1;c<=3;c++)
    	    for(int i=1;i<=n;i++)
    	        for(int j=1;j<=m;j++)
    		        mn[col[i][j]][c] = mn[c][col[i][j]] = min(mn[c][col[i][j]],d[c][i][j]);
        ans = min(mn[1][2]+mn[2][3],min(mn[1][3]+mn[3][2],mn[3][1]+mn[1][2]));
        for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++)
    	        ans = min(ans,d[1][i][j]+d[2][i][j]+d[3][i][j]);
        printf("%d
    ",ans-2);
        return 0;
    }
    
  • 相关阅读:
    MongoDB 学习笔记(七):主从复制与副本集
    MongoDB 学习笔记(六):备份与用户管理
    MongoDB 学习笔记(五):固定集合、GridFS文件系统与服务器端脚本
    MongoDB 学习笔记(四):索引
    MongoDB 学习笔记(三):分页、排序与游标
    MongoDB 学习笔记(一):安装及简单shell操作
    MongoDB 学习笔记(二):shell中执行增删查改
    mongoDB 入门指南、示例
    mongoDB 介绍(特点、优点、原理)
    企业级任务调度框架Quartz(7) 线程在Quartz里的意义(1)
  • 原文地址:https://www.cnblogs.com/BCOI/p/8909970.html
Copyright © 2011-2022 走看看