每次将不转弯能到的点全部标记(标记转弯次数)接着也只能由这些点扩展了,,将它们能到的所有点标记,同时转弯次数加1。
Convex Shape CodeForces - 275B
//暴力搜索非递归
#include<stdio.h>
#include<string.h>
int n,m;
int book[120][120];
char a[120][120];
int dfs(int x,int y,int c){
int flag=0;//判断是否标记地图,没再标记就证明标记工作已经完成
for(int i=x+1;i<=n;i++) //右
if(book[i][y]==0){book[i][y]=c;flag=1;} //只标记没标记过的,若标记跳过继续标记.
else if(book[i][y]==-1) break;
for(int i=x-1;i>=1;i--) //左
if(book[i][y]==0){book[i][y]=c;flag=1;}
else if(book[i][y]==-1) break;
for(int i=y+1;i<=m;i++) //上
if(book[x][i]==0){book[x][i]=c;flag=1;}
else if(book[x][i]==-1) break;
for(int i=y-1;i>=1;i--) //下
if(book[x][i]==0){book[x][i]=c;flag=1;}
else if(book[x][i]==-1) break;
return flag;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%s",a[i]+1);
int startx,starty,endx,endy,k;
scanf("%d%d%d%d%d",&k,&starty,&startx,&endy,&endx);
if(startx==endx&&starty==endy){printf("yes\n");continue;} //可能的数据
if(a[endx][endy]=='*'){printf("no\n");continue;} //可能的数据
memset(book,0,sizeof(book));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]=='*') book[i][j]=-1; //传地图到book二维数组
book[startx][starty]=1; //初始化
dfs(startx,starty,1); //初始化
int c=1; //初始化
while(1){ //开始进入循环
int flag=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(book[i][j]==c){if(dfs(i,j,c+1)) flag=1;}
}
if(flag==0) break;
c+=1;
}
if(book[endx][endy]<=k+1&&book[endx][endy]!=0){printf("yes\n");}//book[endx][endy]!=0条件让我wr了好久
else printf("no\n");
}
return 0;
}
第二次碰到这题,没想着去暴力,wr的很惨,标记了8个方向,每个格的入和出各四个方向,下次补下。
思路:book数组标由标记走没走过改为标记拐弯数即可,用优先队列优先最小拐弯数的点扩展。(只是写法不同,思路延续的还是上面代码)
#include<bits/stdc++.h>
using namespace std;
const int N=100,inf=9999999;
char a[N+10][N+10];
int book[N+10][N+10];
struct node
{
int x,y,dir,k;
friend bool operator < (node p,node q){return p.k>q.k;}
};
priority_queue<node>que,pq;
int bfs(int n,int m,int kk,int startx,int starty,int endx,int endy)
{ //printf("&&%d %d %d %d %d\n",startx,starty,endx,endy,kk);
int next[5][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}};
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
book[i][j]=inf;
while(!que.empty()) que.pop();
node temp;temp.x=startx,temp.y=starty,temp.dir=0,temp.k=0;
que.push(temp);
while(!que.empty())
{
node temp1=que.top();
//printf("=%d %d %d %d\n",temp1.x,temp1.y,temp1.dir,temp1.k);
que.pop();
for(int i=1;i<=4;i++)
{
int tx=temp1.x,ty=temp1.y,dir=temp1.dir,k=temp1.k;
tx+=next[i][0],ty+=next[i][1];
if(tx<1||tx>n||ty<1||ty>m||a[tx][ty]=='*') continue;
if((dir==1&&i==3)||(dir==2&&i==4)||(dir==3&&i==1)||(dir==4&&i==2))continue;
if(dir==0) {dir=i;}
if(dir!=i) {k+=1;dir=i;}
//printf("tx=%d ty=%d dir=%d k=%d %d\n",tx,ty,dir,k,book[tx][ty]);
if(k>kk||k>book[tx][ty]) continue;
if(tx==endx&&ty==endy){return 1;}
book[tx][ty]=k;
node temp2;temp2.x=tx,temp2.y=ty,temp2.k=k,temp2.dir=dir;
que.push(temp2);
}
}
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
int k,startx,starty,endx,endy;
scanf("%d%d%d%d%d",&k,&starty,&startx,&endy,&endx);
if(startx==endx&&starty==endy){printf("yes\n");continue;}
int flag=bfs(n,m,k,startx,starty,endx,endy);
if(flag) printf("yes\n");
else printf("no\n");
}
return 0;
}
再次遇到相关题目选择了很暴力的广搜
思路:book数组用来计数,无标记的广搜直到转弯超过1次终止,等同深搜。做法很危险,要是转5次10次呢.(该代码就危险了,额,快超时了600多)
没深刻理解上面正解原理,这类题采用暴力原理,优先的写法,思路对代码实现应变性强.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf=9999999;
int n,m,num;
char a[60][60];
int book[60][60];
struct node
{
int x,y,k,dir;
};
queue<node>que;
int bfs(int startx,int starty)
{
int u=0;
memset(book,0,sizeof(book));
int next[5][2]={0,0,0,1,1,0,0,-1,-1,0};
while(!que.empty()) que.pop();
node temp;temp.x=startx,temp.y=starty,temp.k=0,temp.dir=0;
que.push(temp);
book[startx][starty]=1;
u++;
while(!que.empty())
{
node temp1=que.front();
que.pop();
for(int i=1;i<=4;i++)
{
int tx=temp1.x+next[i][0],ty=temp1.y+next[i][1],k=temp1.k,dir=temp1.dir;
if(tx<1||tx>n||ty<1||ty>m||a[tx][ty]=='W') continue;
if(dir==0) dir=i;
if(i==1&&dir==3||i==2&&dir==4||i==3&&dir==1||i==4&&dir==2) continue;
if(dir!=i){dir=i;k++;}
if(k>=2){continue;}
if(!book[tx][ty]){book[tx][ty]=1;u++;}
node temp2;temp2.x=tx,temp2.y=ty,temp2.k=k,temp2.dir=dir;
que.push(temp2);
}
}
if(u==num) return 1;
return 0;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
num=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]=='B')
{
num++;
}
int flag=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!flag&&a[i][j]=='B')
{
if(bfs(i,j)==0){flag=1;break;}
}
if(flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}
Convex Shape CodeForces - 275B