电路维修(信息学奥赛一本通-T1448)
【题目描述】
译自 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)相关推荐
- 信息学奥赛一本通_长乐一中老师演绎“奥赛传奇”
董永建(右一)在课堂上. 台海网5月14日讯 据福州晚报报道,长乐一中有一位"传奇"老师--15年来,他辅导的学生在全国高中生信息学奥赛中获金牌3人次.银牌3人次.铜牌5人次:在全 ...
- 信息学奥赛一本通 提高篇 第5章 矩阵乘法
例1 矩阵AXB 信息学奥赛一本通(C++版)在线评测系统 [矩阵乘法]矩阵A×B_Uletay-CSDN博客 矩阵乘法--矩阵A×B_vina的博客-CSDN博客 一本通1641[例 1]矩阵 A× ...
- 《信息学奥赛一本通提高篇》第6章 组合数学
例1 计算系数(NOIP2011提高) 信息学奥赛一本通(C++版)在线评测系统 NOIP2011计算系数_nanhan27的博客-CSDN博客 「NOIP2011」 计算系数 - 组合数_TbYan ...
- 《信息学奥赛一本通 提高篇》
提高篇 第一部分 基础算法 第1章 贪心算法 提高篇 第一部分 基础算法 第1章 贪心算法_青少年趣味编程-CSDN博客 提高篇 第一部分 基础算法 第1章 贪心算法 提高篇 第一部分 基础算法 第1 ...
- 信息学奥赛一本通 提高篇 第一部分 基础算法 第2章 二分与三分
信息学奥赛一本通 提高篇 提高版 第一部分 基础算法 第2章 二分与三分 信息学奥赛一本通 提高篇 提高版 第一部分 基础算法 第2章 二分与三分_mrcrack的博客-CSDN博客_信息学奥赛一本通 ...
- 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题
第1章 快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章 素数 第 3 章 约数 第 4 章 同余问题 第 5 章 矩阵乘法 第 6 章 ...
- 信息学奥赛一本通 1080:余数相同问题 2022.1.29 AC
http://ybt.ssoier.cn:8088/show_source.php?runid=14630195 /* 信息学奥赛一本通 1080:余数相同问题 2022.1.29 AC http:/ ...
- 信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂
信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂 https://blog.csdn.net/mrcrack/article/details/82846727 快速幂取模算法如何实现? h ...
- 【例1】 0/1背包《信息学奥赛一本通》【解法一】 02
/* [例1] 0/1背包<信息学奥赛一本通>[解法一] 02 http://ybt.ssoier.cn:8088/problem_show.php?pid=1267 */ #includ ...
最新文章
- [CF843D]Dynamic Shortest Path
- 死磕Java并发:Java内存模型之分析volatile
- MySQL中数据库的操作
- Cracer渗透视频课程学习笔记——漏洞分析
- Boost:mighty bimap强大的双图的测试程序
- python作品_Python爬取图虫网摄影作品
- 房价预测python_详解 Kaggle 房价预测竞赛优胜方案:用 Python 进行全面数据探索...
- static静态关键词 1214
- java sql 联表查询系统_Spring Hibernate JPA 联表查询 复杂查询(转)
- 【转】程序员技术练级攻略
- oracle知否有用coherence,Oracle Coherence概述
- html调查问卷页面,html+js 问卷调查页面的展示以及form提交
- MSP430加密代码保护
- 线路规划实现用java_北京地铁出行线路规划系统项目总结(Java+Flask+Vue实现)
- 结构思考力~设计序言
- vmware未识别网络
- 第2季极客沙龙资料分享 - 知行·前端体验主题交流会
- Keras_examples
- 自动组策略(GPO)备份工具
- 用Linux开发板制作智能音箱,【工程师实战】只要几步,普通音箱秒变小度智能音箱...