【宽搜】【并查集】Vijos P1015 十字绣
题目链接:
https://vijos.org/p/1015
题目大意:
n*m的网格,线只能在网格的顶点处才能从布的一面穿到另一面。每一段线都覆盖一个单位网格的两条对角线之一,而在绣的过程中,一针中连续的两段线必须分处布的两面。
给出布两面的图案,问最少需要几针才能绣出来?一针是指针不离开布的一次绣花过程。
题目思路:
【宽搜】或【并查集】
正面的如果有线就把端点连正边,反面连负边。
一针就是从正边到反边再到正边这样循环下去。用宽搜写floodfill(或者并查集)把一次走到线路抠出来,线路上|正边数-反边数|/2为该线路的针数。
感觉自己说不太清楚,引用大牛zhymaoiing的话:
将正面的边视为正边,反面的则视为负边。用floodfill将由正边和负边交替连接的结点组成一个块。对于每一个块,其中的所有结点的正边数目和负边数目之差的绝对值(定为dep)之后div 2后就为这个块的所需针数。
在一个块中只用一针就可完成,假设该针由v1出发,到vn结束,那么v1到vn中间的点的dep为0,而v1和vn则为1。也就是说块中的那一针在v1有一个入口,在vn有一个出口,而每一对入口和出口就代表了一针,那么就可以通过dep之和除以2得到所需针数。由此可以拓宽到多针。
//
//by coolxxx
//
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<memory.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
#define eps 1e-8
#define J 10
#define MAX 0x7f7f7f7f
#define PI 3.1415926535897
#define N 207
using namespace std;
int n,m,lll,ans,cas;
char map[2][N][N];
bool u[N][N];
bool f;
void floodfill(int i,int j)
{int t=0,k;if(u[i][j])return;u[i][j]=1;if(i>1 && j>1){for(k=0;k<2;k++){if(map[k][i-1][j-1]=='\\' || map[k][i-1][j-1]=='X'){t=t+(-2)*k+1;f=1;floodfill(i-1,j-1);}}}if(i>1 && j<=m){for(k=0;k<2;k++){if(map[k][i-1][j]=='/' || map[k][i-1][j]=='X'){t=t+(-2)*k+1;f=1;floodfill(i-1,j+1);}}}if(i<=n && j>1){for(k=0;k<2;k++){if(map[k][i][j-1]=='/' || map[k][i][j-1]=='X'){t=t+(-2)*k+1;f=1;floodfill(i+1,j-1);}}}if(i<=n && j<=m){for(k=0;k<2;k++){if(map[k][i][j]=='\\' || map[k][i][j]=='X'){t=t+(-2)*k+1;f=1;floodfill(i+1,j+1);}}}lll+=abs(t);
}
int main()
{#ifndef ONLINE_JUDGE
// freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);#endifint i,j,k;
// while(~scanf("%s",s1))while(~scanf("%d",&n))
// for(scanf("%d",&cas),l=1;l<=cas;l++){memset(u,0,sizeof(u));ans=0;scanf("%d",&m);for(k=0;k<2;k++)for(i=1;i<=n;i++)scanf("%s",map[k][i]+1);for(i=1;i<=n+1;i++){for(j=1;j<=m+1;j++){lll=f=0;floodfill(i,j);if(f && lll==0)ans++;else ans+=lll/2;}}printf("%d\n",ans);}return 0;
}/*
////
*/
//
//by coolxxx
//
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<memory.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
#define eps 1e-8
#define J 10
#define MAX 0x7f7f7f7f
#define PI 3.1415926535897
#define N 207
using namespace std;
int n,m,lll,ans,cas,cass;
int a[N*N],b[N*N],fa[N*N],c[N*N];
bool u[N*N],v[N*N];
char map[2][N][N];
int zhao(int aa)
{if(fa[aa]==-1)return aa;return fa[aa]=zhao(fa[aa]);
}
int main()
{#ifndef ONLINE_JUDGE
// freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);#endifint i,j,k,x,y,fx,fy;
// while(~scanf("%s",s1))while(~scanf("%d",&n))
// for(scanf("%d",&cas),cass=1;cass<=cas;cass++){memset(fa,-1,sizeof(fa));memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(u,0,sizeof(u));memset(v,0,sizeof(v));ans=0;c[0]=0;scanf("%d",&m);for(k=0;k<2;k++)for(i=0;i<n;i++)scanf("%s",map[k][i]);for(k=0;k<2;k++){for(i=0;i<n;i++){for(j=0;j<m;j++){if(map[k][i][j]=='\\' || map[k][i][j]=='X'){x=i*(m+1)+j;y=(i+1)*(m+1)+j+1;fx=zhao(x);fy=zhao(y);if(fx!=fy)fa[fy]=fx;a[x]+=(-2)*k+1;a[y]+=(-2)*k+1;v[x]=v[y]=1;}if(map[k][i][j]=='/' || map[k][i][j]=='X'){x=i*(m+1)+j+1;y=(i+1)*(m+1)+j;fx=zhao(x);fy=zhao(y);if(fx!=fy)fa[fy]=fx;a[x]+=(-2)*k+1;a[y]+=(-2)*k+1;v[x]=v[y]=1;}}}}for(i=0;i<(n+1)*(m+1);i++){if(!v[i])continue;j=zhao(i);if(!u[j])u[j]=1,c[++c[0]]=j;b[j]+=abs(a[i]);}for(i=1;i<=c[0];i++){if(b[c[i]]==0)ans++;else ans+=b[c[i]]/2;}printf("%d\n",ans);}return 0;
}/*
////
*/
【宽搜】【并查集】Vijos P1015 十字绣相关推荐
- 力扣 547. 朋友圈 c语言 三种解法 深搜 广搜 并查集。
题目: 并查集: /*力扣 547 朋友圈 并查集 c语言 2020/12/14 1:04 by ksks14*/ /*初始化 查找 合并*/ #define maxsize 10000 int fl ...
- 图 相关算法~从头学算法【广搜、 深搜、 拓扑排序、 并查集、 弗洛伊德算法、迪杰斯特拉算法】
图的相关主流算法主要有: 广度优先搜索 深度优先搜索 拓扑排序 并查集 多源最短路径(弗洛伊德算法) 单源最短路径(迪杰斯特拉算法) 其中呢,最基本的是前两种,也就是平时常用的广搜和深搜,本文中将概要 ...
- 货车运输 vijos 1843 NOIP2013 D1T3 最大生成树,并查集,(伪·LCA)
(本人比较笨,没写LCA,在树上暴力跑过了此题.) 可以证明答案一定在最大生成树上,因为如果答案比最大生成树上的路径更优,那么最大生成树一定不是正确的.反证之. 同时注意到最大生成树过程中是使用了并查 ...
- L2-026 小字辈——BFS DFS 并查集-三种方法
输入格式: 输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) -- 简单起见,我们把家族成员从 1 到 N 编号.随后第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的 ...
- hdu 1811 Rank of Tetris (并查集+拓扑排序)
Problem - 1811 感觉这题的并查集以及拓扑排序并不难,但是做题的时候必须理解到矛盾(CONFLICT)与不确定(UNCERTAIN)直接的优先关系. 做这题的时候,构图什么的很简单,就是没 ...
- 连通图的判断(并查集, DFS, BFS)
首先要明确什么是连通图??? 连通图:对于一个图来说,图中的任意一个点都能访问到所有的点,则说明该图连通 很明显,如果要判断一个图是否连通,则必须要从任意一个搜索一遍,判断是否到达了所有的点,则很快会 ...
- pku2524-----Ubiquitous Religions(初次接触并查集)
方法一:time limited:对于合并操作要搜遍全部元素 Code //并查集 //方法一:用集合中最小元素标记集合. //对于合并操作要搜遍全部元素. #include<stdio.h&g ...
- hdu1181变形课dfs/bfs/并查集三种解法(java)
题目链接 Problem Description 呃-变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个 ...
- 蓝桥杯 历届试题 合根植物(并查集)
传送门 题目描述 w星球的一个种植园,被分成 m * n个小格子(东西方向m行,南北方向n列).每个格子里种了一株合根植物. 这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植 ...
最新文章
- 网络推广——网络推广专员优化网站有秘诀!
- 线程的常用方法——currentThread方法||在main方法中直接调用run()方法,没有开启新的线程,以在run方法中的当前线程就是main线程||启动子线程,子线程会调用run方法
- QML做类似Android圆形头像
- [leetcode] 141.环形链表
- python设计模式(十四):模板方法模式
- 基于C#的计时管理器
- IE与IE内核浏览器的那点事
- 程序员,你能真正掌握多少编程技术?
- Openresty 安装、源码编译,增加WAF模块naxsi
- 生命游戏(Anylogic实现)
- 管理信息系统开发方法——原型法
- Linux 卸载及删除磁盘分区
- [Golang] Goland 编辑器 替换快捷键
- IDEA This inspection performs unresolved SQL references check
- 广告点击率预估是怎么回事?
- 一文看懂GPIO口的八种工作原理
- POI之Excel单元格样式
- 高效的敏捷测试第四课 测试的团队协作
- SpringBoot与MongoDB的集成使用
- 正宇控股带你认识区块链技术
热门文章
- 【OTT】国广东方OTT盈利模式
- 趋高智能机器视觉图像目标尺寸检测尺寸测量的应用方案
- SVF生成PDF报表,怎样实现换行
- GO-micro入门
- 开源项目-旅游信息管理系统
- 杨建允:直播短视频内容营销趋势下,企业要更加重视私域流量运营
- lol服务器维护 胜率,英雄联盟:服务器当真会强行平衡胜率,玩家连胜之后必定连跪?...
- 支持PD快充验证带DVM数字电压表利器—2串电池组电池模拟器
- SQL Server 2008 正式版下载地址+安装指南+序列号
- win10系统上传服务器很慢,Windows10下局域网传输速度很慢的两种解决方案