• 洛谷 P1524 十字绣


    题目背景

    考古学家发现了一块布,布上做有针线活,叫做“十字绣”,即交替地在布的两面穿线。

    题目描述

    布是一个n*m的网格,线只能在网格的顶点处才能从布的一面穿到另一面。每一段线都覆盖一个单位网格的两条对角线之一,而在绣的过程中,一针中连续的两段线必须分处布的两面。给出布两面的图案(实线代表该处有线,虚线代表背面有线),问最少需要几针才能绣出来?一针是指针不离开布的一次绣花过程。

    输入输出格式

    输入格式:

     

    第1行两个数N和M(1<=N,M<=200)。

    接下来N行每行M个数描述正面。

    再接下来N行每行M个数描述反面。

    每个格子用.(表示空),/(表示从右上角连到左下角),(表示从左上角连到右下角)和X(表示连两条对角线)表示

     

    输出格式:

     

    一个数,最少要用的针数。

     

    输入输出样例

    输入样例#1:
    4 5
    .....
    ....
    ....
    .....
    .....
    .... 
    .X..
    .....
    
    输出样例#1:
    4
    思路:然而我并不会(⊙o⊙)…可能是并查集吧!
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int n,m,num,sum,ans;
    int map[300][300];
    char s[3][201][201];
    int b[50000],c[50000];
    int fa[50000],val[50000],vis[50000];
    int find(int x){
        if(fa[x]==x)    return x;
        else return fa[x]=find(fa[x]);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%s",s[1][i]);
        for(int i=1;i<=n;i++)
            scanf("%s",s[2][i]);
        for(int k=1;k<=2;k++)
            for(int i=1;i<=n;i++)
                for(int j=0;j<m;j++){
                    if(s[k][i][j]=='/'||s[k][i][j]=='X'){
                        if(map[j+2][i]==0){
                            num++;
                            fa[num]=num;
                            map[j+2][i]=num;
                        }
                        if(map[j+1][i+1]==0){
                            num++;
                            fa[num]=num;
                            map[j+1][i+1]=num;
                        }
                        val[map[j+2][i]]+=2*k-3;
                        val[map[j+1][i+1]]+=2*k-3;
                        int dx=find(map[j+2][i]);
                        int dy=find(map[j+1][i+1]);
                        if(dx!=dy)    fa[dy]=dx;
                    }
                    if(s[k][i][j]==92||s[k][i][j]=='X'){
                        if(map[j+1][i]==0){
                            num++;
                            fa[num]=num;
                            map[j+1][i]=num;
                        }
                        if(map[j+2][i+1]==0){
                            num++;
                            fa[num]=num;
                            map[j+2][i+1]=num;
                        }
                        val[map[j+1][i]]+=2*k-3;
                        val[map[j+2][i+1]]+=2*k-3;
                        int dx=find(map[j+1][i]);
                        int dy=find(map[j+2][i+1]);
                        if(dx!=dy)    fa[dy]=dx;
                    }
                }
        for(int i=1;i<=num;i++){
            int dx=find(i);
            if(vis[dx]==0){
                sum++;
                c[sum]=dx;
                vis[dx]=1;
            }
            b[dx]=b[dx]+abs(val[i]);
        }
        for(int i=1;i<=sum;i++){
            if(b[c[i]]==0)    b[c[i]]=1;
            ans=ans+(b[c[i]]+1)/2;
        }
        cout<<ans;
    }
     
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    双六
    除法取模
    欧拉函数及费马小定理
    基础模运算
    Leeetcode--581. Shortest Unsorted Continuous Subarray
    Codeforces Round #541--1131F. Asya And Kittens(基础并查集)
    leetcode--200. Number of Islands
    leetcode--21. Merge Two Sorted Lists
    leetcode--155. Min Stack
    Codeforces Round #539--1113B
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7582548.html
Copyright © 2020-2023  润新知