P1162 填涂颜色
#include
using namespace std;
int mp[35][35];
bool inq[35][35];
int n;
pairNode(0,0);
int dr[8][2]=
{
{-1,0},{0,-1},{0,1},{1,0}
};
void BFS(){
queue>q;
q.push(Node);
while(!q.empty()){
auto top=q.front();
q.pop();
for(int i=0;i<4;++i){
int newx=top.first+dr[i][0],newy=top.second+dr[i][1];
if(newx<=n+1&&newx>=0&&newy<=n+1&&newy>=0&&!inq[newx][newy]
&&!mp[newx][newy]&&mp[newx][newy]==mp[top.first][top.second]){
q.push({newx,newy});
inq[newx][newy]=true;
}
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;++i){//0,n+1当做墙
for(int j=1;j<=n;++j){
scanf("%d",&mp[i][j]);
}
}
BFS();
for(int i=1;i<=n;++i) {
for(int j=1;j<=n;++j){
if(inq[i][j])printf("0 ");
else if(mp[i][j]==0)printf("2 ");
else printf("1 ");
}
printf("\n");
}
}
说明:可以把题目中矩阵的边界设为[1,n],留出第0行、第0列、第n+1行和第n+1列(初值为0),从(0,0)开始搜索,标记和(0,0)连通的块(用 bool inq[][] 标记),那么被标记的连通块一定是1形成的闭合圈以外的所有块。
P1141 01迷宫
#include
#include
#include
#include
using namespace std;
struct node{
int x,y;
}Node;
int n,m,ans;
char a[1001][1001];
int vis[1001][1001];
int mark=1;
int res[100005];
int X[4]={-1,1,0,0},Y[4]={0,0,-1,1} ;
void BFS(){
queueq;
q.push(Node);
while(!q.empty()){
node top=q.front();
q.pop();
for(int i=0;i<4;++i){
int newx=top.x+X[i],newy=top.y+Y[i];
if(a[top.x][top.y]!=a[newx][newy]&&!vis[newx][newy]&&newx>=1&&newx<=n&&newy>=1&&newy<=n){//
q.push({newx,newy});//
vis[newx][newy]=mark;
++ans;
}
}
}
res[mark]=ans;
mark++;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%s",a[i]+1);//
}
for(int i=0;i
说明:
1.A点若能到达B点,B点也一定能到达A点,求连通块的数目并保存,下次遇到直接查询。不用这个方法会TLE。
2.inq数组不仅能标记某点是否已入队(防止重复入队),在此题中可以直接利用它保存每个点连通块的数目。
P1443 马的遍历
#include
using namespace std;
struct node{
int x,y;
}Node;
int inq[405][405];
int n,m,ans;
int dr[8][2]={
{2,1},{1,2},
{-1,2},{-2,1},
{-2,-1},{-1,-2},
{1,-2},{2,-1}
};
void BFS(){
queueq;
q.push(Node);
while(!q.empty()){
node top=q.front();
q.pop();
for(int i=0;i<8;++i){
int nx=top.x+dr[i][0],ny=top.y+dr[i][1];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&!inq[nx][ny]){
q.push({nx,ny});
inq[nx][ny]=inq[top.x][top.y]+1;
}
}
}
}
int main(){
scanf("%d%d%d%d",&n,&m,&Node.x,&Node.y);
inq[Node.x][Node.y]=1;
BFS();
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
printf("%-5d",inq[i][j]-1);
}
cout<<"\n";
}
}
说明:
1.这题关键在于dr[8][2]数组保存的方向(马走日)。
2.起始点的inq为1,走到的其他点为inq[nx][ny]=inq[top.x][top.y]+1。输出inq[i][j]-1正好满足题目要求(起始点为0,不能到达则输出-1)。
3.左对齐,宽5格 这样写:printf(" %-5d " , inq[i][j] - 1)。而cout<
%-5d是首列左对齐,输出字符间5个空格
%5d是直接输出字符间5个空格不左对齐
像如下:
%-5d
1 2 3 4
%5d
1 2 3 4