维修电路

两个点,如果有线连接,则边权为0,否则边权为1

如果扩展到一个点,边权是0,则把这个点加入到队列的首端,因为对于权值来说,相当于没扩展

这就是双端队列,这里如果将将要加入的距离与队头的距离比较,会错???

注意不能map[xx][yy]==‘\‘,要map[xx][yy]==‘\\‘

这个代码是照蓝书抄的,这是一个很巧妙的办法,每个map中的x和y都是要比较的两个x和y中的较小值

而我之前写的把点编号的方法一定会MLE,更不必说直接上四维数组的了

还容易写错

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxm=500007;
 6 const int maxn=507;
 7 int d[maxn][maxn];
 8 char map[maxn][maxn];
 9 bool vis[maxn][maxn];
10 pair<int,int>q[maxm*5];
11 int n,m,head=maxm+1,tail=maxm;
12 bool check(int x,int y){
13     if(x<0||x>n||y<0||y>m) return false;
14     else return true;
15 }
16 void q_add(int x,int y,int dis,int opt){
17     if(d[x][y]<0||d[x][y]>dis){
18         d[x][y]=dis;
19         if(opt==0) q[--head]=make_pair(x,y);
20         else q[++tail]=make_pair(x,y);
21     }
22 }
23 int main(){
24     int t;cin>>t;
25     while(t--){
26         memset(d,-1,sizeof(d));d[0][0]=0;
27         memset(vis,false,sizeof(vis));
28         cin>>n>>m;
29         //if((n+m)%2) {cout<<"NO SOLUTION"<<endl;continue;}
30         for(int i=0;i<n;i++) scanf("%s",map[i]);
31         q[++tail]=make_pair(0,0);
32         while(head<=tail){
33             int xx=q[head].first;int yy=q[head].second;head++;
34             if(check(xx-1,yy-1)){
35                 if(map[xx-1][yy-1]==‘\\‘) q_add(xx-1,yy-1,d[xx][yy],0);
36                 else q_add(xx-1,yy-1,d[xx][yy]+1,1);
37             }
38             if(check(xx-1,yy+1)){
39                 if(map[xx-1][yy]==‘/‘) q_add(xx-1,yy+1,d[xx][yy],0);
40                 else q_add(xx-1,yy+1,d[xx][yy]+1,1);
41             }
42             if(check(xx+1,yy-1)){
43                 if(map[xx][yy-1]==‘/‘) q_add(xx+1,yy-1,d[xx][yy],0);
44                 else q_add(xx+1,yy-1,d[xx][yy]+1,1);
45             }
46             if(check(xx+1,yy+1)){
47                 if(map[xx][yy]==‘\\‘) q_add(xx+1,yy+1,d[xx][yy],0);
48                 else q_add(xx+1,yy+1,d[xx][yy]+1,1);
49             }
50         }
51         if(d[n][m]==-1) cout<<"NO SOLUTION"<<endl;
52         else cout<<d[n][m]<<endl;
53     }
54     return 0;
55 } 

如果一开始就判断是错的,要注意也要输入,因为是多组数据,时间复杂度就犯过这个问题

原文地址:https://www.cnblogs.com/lcan/p/9613879.html

时间: 2024-11-09 00:05:15

维修电路的相关文章

自主学习 &amp; 提问的智慧——学习中遇到难题怎么破?

解决问题的流程 在学习的过程中,我们总会有不了解的东西,恰好身边又有大神了解.这时有些人就不假思索开始提问了.我曾经回答过相当多的技术问题. 当自己学习出了问题时,要尽可能独立思考去解决:再考虑通过查阅书籍和网上的资料来解决:实在还是解决不了,再考虑请教别人,而提问也需要智慧. 自主学习的动力来源 人的本性都是充满好奇心,渴望了解一个未知事物的.好奇心的驱使下,人是会主动学习的.就整个人类社会而言,自古就不断的探索宇宙,这就是好奇心的表现,如果把全人类看做一个整体,人类的终极目标,或许就是要找到

洛谷 P2243 电路维修

P2243 电路维修 题目背景 Elf 是来自Gliese 星球的少女,由于偶然的原因漂流到了地球上.在她无依无靠的时候,善良的运输队员Mark 和James 收留了她.Elf 很感谢Mark和James,可是一直也没能给他们帮上什么忙. 题目描述 有一天 Mark 和James 的飞行车没有办法启动了,经过检查发现原来是电路板的故障.飞行车的电路板设计很奇葩,如下图所示: 输入输出格式 输入格式: 输入文件包含多组测试数据.第一行包含一个整数T 表示测试数据的数目. 对于每组测试数据,第一行包

洛谷P2243 电路维修

P2243 电路维修 题目背景 Elf 是来自Gliese 星球的少女,由于偶然的原因漂流到了地球上.在她无依无靠的时候,善良的运输队员Mark 和James 收留了她.Elf 很感谢Mark和James,可是一直也没能给他们帮上什么忙. 题目描述 有一天 Mark 和James 的飞行车没有办法启动了,经过检查发现原来是电路板的故障.飞行车的电路板设计很奇葩,如下图所示: 输入输出格式 输入格式: 输入文件包含多组测试数据.第一行包含一个整数T 表示测试数据的数目. 对于每组测试数据,第一行包

luogu P2243 电路维修

P2243 电路维修 题目背景 Elf 是来自Gliese 星球的少女,由于偶然的原因漂流到了地球上.在她无依无靠的时候,善良的运输队员Mark 和James 收留了她.Elf 很感谢Mark和James,可是一直也没能给他们帮上什么忙. 题目描述 有一天 Mark 和James 的飞行车没有办法启动了,经过检查发现原来是电路板的故障.飞行车的电路板设计很奇葩,如下图所示: 输入输出格式 输入格式: 输入文件包含多组测试数据.第一行包含一个整数T 表示测试数据的数目. 对于每组测试数据,第一行包

学习 研究 修理 ,维修, 电路, 家电

修理 ,维修, 电路, 家电 http://www.haohetao.com/thread-1024305-1-1.html wwbl ft0http://www.haohetao.com/thread-1024306-1-1.html wwbl ft1http://www.haohetao.com/thread-1024308-1-1.html wwbl ft2http://www.haohetao.com/thread-1024309-1-1.html wwbl ft3http://www.

电路维修

[题目描述]: 电路维修 [思路]: 开先看起来挺迷的,觉得没法做,搜索也写不出来... 再仔细分析题目,发现对于任意一根电路,它只有两种状态: 连着右上和坐下 连着左下和右上 要求最小的操作数. 我们可以发现,每条电线可以花费1的代价从一种状态改变为另外一种状态,那么我们可以对于已经连着的两点连一条权为0的边,没连着的连一条花费为1的边,求出从左上角到右下角的最短路即可. 注:卡\(SPFA\),建议用\(SLF\) \(or\) \(LLL\) \(or\) 堆优化的\(DJ\),此处用的\

Luogu2243电路维修

Luogu2243电路维修 传送门 原题 找到左上角到右下角的通路.可以旋转某一个方块,代价为一. lyd书上的例题2333 怎么做 将这个问题转化为从左上到右下的最短路问题.若这个角需要旋转则是权值为1的路径,否则权值为0.这个时候跑最短路就可以了. 由于路径的权值很特殊,我们可以考虑使用双端队列优化.当权值为0时从队头插入,权值为1时从队尾插入.每次取队头,这样就可以保证一直在走最优解.而不需要dijkstra堆优化或者SPFA多次寻找最优解. 码代码时还有优化注释在代码里了. 扔代码 #i

【CH2601】电路维修

这是一道广搜题,难点在于对题目的理解和对细节的处理. 对于一个节点,可以向左上.左下.右上.右下四个位置扩展,根据地图的形态确定每一步扩展的代价. 将代价最小的节点放在队头,这样用双端队列来实现.每个节点最多进出队列一次,所以时间复杂度为O(r*c) 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace s

Luogu_P2243 电路维修【题解】 双端队列bfs

题面:https://www.luogu.org/problem/P2243 建边. 对角线有相连路的边权为0,没有的为1. 然后双端队列bfs求最短路. 将边权为0的到的点从队头入队. 边权为1到的点从队尾入队. 这样可以保证最优. 代码如下: #include<bits/stdc++.h> #define int long long using namespace std; const int maxn=510; int T,r,c,dis[maxn][maxn],vis[maxn][ma