【题目描述】

译自 BalticOI 2011 Day1 T3「Switch the Lamp On」

有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会。

有 N×M 个这样的元件,你想将其排列成 N 行 M 列放在电路板上。电路板的左上角连接电源,右下角连接灯泡。

试求:至少要旋转多少个正方形元件才能让电源与灯泡连通,若无解则输出 NO SOLUTION。

【输入】

有多组测试数据。

第一行为测试数据组数,以下每组测试数据描述为:

第一行有两个整数 N 和 M。

在接下来的 N 行中,每行有 M 个字符。每个字符均为 "\" 或 "/",表示正方形元件上导线的连接方向。

【输出】

每组测试数据输出描述:

输出共一行,若有解则输出一个整数,表示至少要旋转多少个正方形元件才能让电源与灯泡连通;若无解则输出 NO SOLUTION。

【输入样例】

1
3 5
\\/\\
\\///
/\\\\

【输出样例】

1

思路:

问题的关键在于思维的转换,首先,由于从左上到右下走的是对角线,因此,仅当 (n+m)%2==1 时无解,其他情况一定有解

首先进行建图,将格子的字符转为数字,即将 \ 转为 0,将 / 转为 1

然后考虑对角线格子的情况,无非以下四种:\\、\/、//、/\,同时,将这四种情况也转为数字的形式存储,相应的,行走的花费就为 0、1、0、1

再考虑所走的方向:左下、左上、右上、右下

此时,我们对图进行 BFS 搜索,考虑到两种状态:有花费、无花费,由于要使得花费最低,因此每次从队首出队时,我们要选一个无花费的元素出队,故而可利用双端队列 deque 进行优化:当有花费时,从队尾入队,当无花费时,从队首入队,从而保证队列的两端性与单调性

此时只剩下一个问题,就是最小花费的问题,即什么情况下才能将元素入队,我们可以借助一个数组,存储之前的花费,当某一步的花费较之前的花费缩小时,即将元素入队

【源程序】

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;}
LL quickMultPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;}
LL quickPowMod(LL a,LL b,LL mod){ LL res=1; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1; } return res; }
LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-6;
const int MOD = 1000000000+7;
const int N = 1000+5;
const int dx[] = {0,0,-1,1,1,-1,1,1};
const int dy[] = {1,-1,0,0,-1,1,-1,1};
using namespace std;struct Node {int x, y;int step;Node() {}Node(int x, int y, int step) : x(x), y(y), step(step) {}
};
int n, m;
int G[N][N]; //将格子的字符转为数字 0:\ 1:/
int dirG[4][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; /* 对角线格子的情况:\\,\/,//,/\ */
int disG[4] = {0, 1, 0, 1}; //对角线格子相应的状态下是否能走
int dir[4][2] = {{-1, -1}, {-1, 1}, {1, 1}, {1, -1}}; //走对角线的方向:左下,左上,右上,右下
int dis[N][N];
bool vis[N][N];void BFS() {deque<Node> Q;memset(vis, 0, sizeof(vis));memset(dis, INF, sizeof(dis));Q.push_front((Node){0, 0, 0});while (!Q.empty()) {Node node = Q.front();Q.pop_front();int x = node.x, y = node.y;int step = node.step;if (vis[x][y])continue;vis[x][y] = true;if (x == n && y == m) {printf("%d\n", step);return;}for (int i = 0; i < 4; i++) {int gx = x + dirG[i][0];int gy = y + dirG[i][1];if (gx < 0 || gy < 0 || gx > n || gy > m)continue;int nx = x + dir[i][0];int ny = y + dir[i][1];if (nx < 0 || ny < 0 || nx > n || ny > m)continue;if (dis[nx][ny] == INF) {if (G[gx][gy] != disG[i]) {Q.push_back(Node(nx, ny, step + 1));dis[nx][ny] = step + 1;} else {Q.push_front(Node(nx, ny, step));dis[nx][ny] = step;}} else if (G[gx][gy] == disG[i] && step < dis[nx][ny])Q.push_front(Node(nx, ny, step));}}
}
int main() {int t;scanf("%d", &t);while (t--) {scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {char c = getchar();while (c != '\\' && c != '/')c = getchar();if (c == '\\')G[i][j] = 0;elseG[i][j] = 1;}}if ((n + m) % 2)printf("NO SOLUTION\n");elseBFS();}return 0;
}

电路维修(信息学奥赛一本通-T1448)相关推荐

  1. 信息学奥赛一本通_长乐一中老师演绎“奥赛传奇”

    董永建(右一)在课堂上. 台海网5月14日讯 据福州晚报报道,长乐一中有一位"传奇"老师--15年来,他辅导的学生在全国高中生信息学奥赛中获金牌3人次.银牌3人次.铜牌5人次:在全 ...

  2. 信息学奥赛一本通 提高篇 第5章 矩阵乘法

    例1 矩阵AXB 信息学奥赛一本通(C++版)在线评测系统 [矩阵乘法]矩阵A×B_Uletay-CSDN博客 矩阵乘法--矩阵A×B_vina的博客-CSDN博客 一本通1641[例 1]矩阵 A× ...

  3. 《信息学奥赛一本通提高篇》第6章 组合数学

    例1 计算系数(NOIP2011提高) 信息学奥赛一本通(C++版)在线评测系统 NOIP2011计算系数_nanhan27的博客-CSDN博客 「NOIP2011」 计算系数 - 组合数_TbYan ...

  4. 《信息学奥赛一本通 提高篇》

    提高篇 第一部分 基础算法 第1章 贪心算法 提高篇 第一部分 基础算法 第1章 贪心算法_青少年趣味编程-CSDN博客 提高篇 第一部分 基础算法 第1章 贪心算法 提高篇 第一部分 基础算法 第1 ...

  5. 信息学奥赛一本通 提高篇 第一部分 基础算法 第2章 二分与三分

    信息学奥赛一本通 提高篇 提高版 第一部分 基础算法 第2章 二分与三分 信息学奥赛一本通 提高篇 提高版 第一部分 基础算法 第2章 二分与三分_mrcrack的博客-CSDN博客_信息学奥赛一本通 ...

  6. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  7. 信息学奥赛一本通 1080:余数相同问题 2022.1.29 AC

    http://ybt.ssoier.cn:8088/show_source.php?runid=14630195 /* 信息学奥赛一本通 1080:余数相同问题 2022.1.29 AC http:/ ...

  8. 信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂

    信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂 https://blog.csdn.net/mrcrack/article/details/82846727 快速幂取模算法如何实现? h ...

  9. 【例1】 0/1背包《信息学奥赛一本通》【解法一】 02

    /* [例1] 0/1背包<信息学奥赛一本通>[解法一] 02 http://ybt.ssoier.cn:8088/problem_show.php?pid=1267 */ #includ ...

最新文章

  1. [CF843D]Dynamic Shortest Path
  2. 死磕Java并发:Java内存模型之分析volatile
  3. MySQL中数据库的操作
  4. Cracer渗透视频课程学习笔记——漏洞分析
  5. Boost:mighty bimap强大的双图的测试程序
  6. python作品_Python爬取图虫网摄影作品
  7. 房价预测python_详解 Kaggle 房价预测竞赛优胜方案:用 Python 进行全面数据探索...
  8. static静态关键词 1214
  9. java sql 联表查询系统_Spring Hibernate JPA 联表查询 复杂查询(转)
  10. 【转】程序员技术练级攻略
  11. oracle知否有用coherence,Oracle Coherence概述
  12. html调查问卷页面,html+js 问卷调查页面的展示以及form提交
  13. MSP430加密代码保护
  14. 线路规划实现用java_北京地铁出行线路规划系统项目总结(Java+Flask+Vue实现)
  15. 结构思考力~设计序言
  16. vmware未识别网络
  17. 第2季极客沙龙资料分享 - 知行·前端体验主题交流会
  18. Keras_examples
  19. 自动组策略(GPO)备份工具
  20. 用Linux开发板制作智能音箱,【工程师实战】只要几步,普通音箱秒变小度智能音箱...

热门文章

  1. 西方餐厅的顶级食材,被中国人干到了“白菜价”
  2. 写给中学生的算法入门:学代码之前看这篇就够了
  3. 数据告诉你,抖音是怎么在半年之内逆袭的
  4. crystal ball 软件_推荐10个堪称神器的软件工具
  5. 右军:为张逸《解构领域驱动设计》推荐序
  6. 缓存,确实很香,却也很受伤!
  7. Logback 整合 RabbitMQ 实现统一日志输出
  8. 通过 Chrome Workspace 调试本地项目
  9. linux redhat 下让redis以服务方式运行
  10. jeecg-framework 采用eclipse-maven运行