1175连连看
文章目录
题意:
给出一个 n ∗ m n*m n∗m的棋盘,玩一个类似于连连看的游戏。
1 2 3 4
0 0 0 0
4 3 2 10 : 空 格 {\color{red}0:空格} 0:空格
其 他 : 不 同 的 棋 子 {\color{red}其他:不同的棋子} 其他:不同的棋子
给定棋盘以后,给定起点 s t a r t x , s t a r t y start_x,start_y startx,starty和终点 e n d x , e n d y end_x,end_y endx,endy,要求从起点走到终点,方向转折的次数不能超过2次。
思路:
这题的限制不再是步数,而是转折次数,这就注定了我们不能和正常的bfs一样拓展。
那么该如何拓展呢,既然是以转折次数为限制,我们就一次性把一条直线上可以拓展的点全部拓展,具体见下图。1 2 3 4
0 0 0 0
4 3 2 1
数字为转折次数,起点特殊记录为-1。
起点为 ( 1 , 1 ) (1,1) (1,1),终点为 ( 3 , 4 ) (3,4) (3,4)
每次都往四个方向进行直线拓展。
拓展部分代码示例如下:
for(int i = 0 ; i < 4 ; i++)
{
int tx = temp.x + ne[i][0];
int ty = temp.y + ne[i][1];
while(OK(tx,ty))
{
que[++tail] = {tx,ty,temp.step+1};
book[tx][ty] = true;
tx += ne[i][0];
ty += ne[i][1];
}
}
时间复杂度:
O ( n ∗ m ∗ q ) O(n*m*q) O(n∗m∗q)
AC代码:
#include<bits/stdc++.h>
typedef long long ll;
const int N = 1e3+10,M = 2e4+10,INF = 0x3f3f3f3f,mod = 1e9+7;
struct Node{
int x,y,step;
}que[N*N];
int a[N][N];
bool book[N][N];
int ne[4][2] = {0,1,1,0,0,-1,-1,0};
int n,m,start_x,start_y,end_x,end_y;
bool OK(int x,int y)
{
if(x==end_x&&y==end_y)return true;
if(x < 1||y < 1||x > n||y > m||book[x][y]||a[x][y])return false;
return true;
}
void bfs()
{
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)book[i][j] = false;
int head = 0,tail = -1;
std::cin>>start_x>>start_y>>end_x>>end_y;
if(a[start_x][start_y]!=a[end_x][end_y]||a[start_x][start_y]==0||a[end_x][end_y]==0)
{
std::cout<<"NO\n";
return;
}
que[++tail] = {start_x,start_y,-1};
book[start_x][start_y] = true;
while(tail>=head)
{
auto temp = que[head++];
if(temp.x == end_x && temp.y == end_y)
{
std::cout<<"YES\n";
return;
}
if(temp.step==2)continue;
for(int i = 0 ; i < 4 ; i++)
{
int tx = temp.x + ne[i][0];
int ty = temp.y + ne[i][1];
while(OK(tx,ty))
{
que[++tail] = {tx,ty,temp.step+1};
book[tx][ty] = true;
tx += ne[i][0];
ty += ne[i][1];
}
}
}
std::cout<<"NO\n";
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
while(std::cin>>n>>m)
{
if(n==0&&m==0)break;
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)std::cin>>a[i][j];
int q;
std::cin>>q;
while(q--)
{
bfs();
}
}
return 0;
}