【十二月】第二次课堂练习

P1605

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int barrier[10][10];
int walkx[5] = {0,0,0,1,-1};  //x方向可以走的选择
int walky[5] = {0,-1,1,0,0};  //y方向可以走的选择
int n,m,t,sx,sy,fx,fy;  //n行,m列,t障碍数,sx,sy起点坐标,fx,fy终点坐标 
int result = 0;
int flag[10][10];

void dfs(int x, int y){
    if(x == fx && y == fy){
        result++;
        return;  //返回 
    }
    else{
        for(int i = 1; i <= 4; ++i){  //上下左右四个方向可以走 
            if(flag[x+walkx[i]][y+walky[i]] == 0
             && barrier[x+walkx[i]][y+walky[i]] == 1){  //是否已走过 && 是否有障碍 
                flag[x][y] = 1;  //原先的标记为已走过 
                dfs(x+walkx[i],y+walky[i]);
                flag[x][y] = 0;  //回溯 
            }
        }
    }
}

int main(){
    scanf("%d%d%d",&n,&m,&t);
    scanf("%d%d%d%d",&sx,&sy,&fx,&fy);
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= m; ++j){
            barrier[i][j] = 1;  //初始化为地图都不为障碍,即都可以走 
        }
    }
    int barrierx,barriery;
    for(int i = 1; i<= t; ++i){
        scanf("%d%d",&barrierx,&barriery);
        barrier[barrierx][barriery] = 0;  //更新障碍处 
    }
    dfs(sx,sy);  //从起点开始深搜 
    printf("%d\n",result);
    return 0;
}
View Code

 P1451

dfs:

#include<bits/stdc++.h>
using namespace std;
int g[105][105];
int n,m,sum=0;
bool used[105][105];//标记数组
int dx[]={0,0,1,-1};//方向数组
int dy[]={1,-1,0,0};
//判断边界或是否被标记过
bool check(int a,int b)
{
    if(a<1||a>n||b<1||b>m||g[a][b]==0||used[a][b]==false)
        return false;
    else 
        return true;
}
//深搜
void dfs(int a,int b)
{
    used[a][b]=false;
    for(int i=0;i<4;i++)
    {
        int tx,ty;
        tx=a+dx[i];ty=b+dy[i];
        if(!check(tx,ty))
            continue;  
        dfs(tx,ty);
        used[tx][ty]=false;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%1d",&g[i][j]);//有两种输入方法,当用char定义g[i][j]时,用printf("%s",g[i]);;用int定义g[i][j]时,用scanf("%1d",&g[i][j]);来控制输入的个数
            used[i][j]=true;
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(g[i][j]!=0&&used[i][j])
            {
                dfs(i,j);
                sum++;
            }
        }
        printf("%d",sum);
    return 0;
}
View Code

 bfs:

#include<bits/stdc++.h>
using namespace std;
int g[105][105];
struct node{
    int x,y;
};
int n,m,sum=0;
bool used[105][105];//标记数组
int dx[]={0,0,1,-1};//方向数组
int dy[]={1,-1,0,0};
//判断边界或是否被标记过
bool check(int a,int b)
{
    if(a<1||a>n||b<1||b>m||g[a][b]==0||used[a][b]==false)
        return false;
    else 
        return true;
}
//广搜
void bfs(int a,int b)
{
    queue<node> q;
    node now,next;
    used[a][b]=false;
    now.x=a;now.y=b;
    q.push(now);//入队
    while(!q.empty())
    {
        now=q.front();//返回队首元素
        for(int i=0;i<4;i++)
        {
            int tx=now.x+dx[i];
            int ty=now.y+dy[i];
            if(!check(tx,ty))
                continue;
            next.x=tx;next.y=ty;
            used[tx][ty]=false;
            q.push(next);
        }
        q.pop();//首元素出队
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%1d",&g[i][j]);
            used[i][j]=true;
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(g[i][j]!=0&&used[i][j])
            {
                bfs(i,j);
                sum++;
            }
        }
        cout<<sum<<endl;
    return 0;
}
View Code

P1784

#include<cstdio>
using namespace std;
const int N=10;
const int group[9][9]=
{
    0,0,0,1,1,1,2,2,2,
    0,0,0,1,1,1,2,2,2,
    0,0,0,1,1,1,2,2,2,
    3,3,3,4,4,4,5,5,5,
    3,3,3,4,4,4,5,5,5,
    3,3,3,4,4,4,5,5,5,
    6,6,6,7,7,7,8,8,8,
    6,6,6,7,7,7,8,8,8,
    6,6,6,7,7,7,8,8,8
};//代表9个3*3的区域 
bool row[N][N],col[N][N],gr[N][N];
//row[i][j]:判断第i行是否出现过数字j
//col[i][j]:判断第i列是否出现过数字j
//gr[i][j]:判断区域i是否出现过数字j 
int sudoku[N][N];//数独 
bool check(int x,int y,int w)
{
    if(row[x][w]||col[y][w]||gr[group[x][y]][w])//若该行 或 该列 或 该3*3区域出现过w 
      return 0;//不能填充w 
    return 1;//可填充 
}
void dfs(int x,int y)
{
    if(x==9)//如果此时棋盘满足约束,则输出 
    {
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
              printf("%d ",sudoku[i][j]);
            printf("\n");
        }
        return;
    }
    int nxtx=x,nxty=y+1;//计算下一个状态 
    if(nxty==9)
      ++nxtx,nxty=0;
    if(sudoku[x][y]!=0)//原来就有数字,直接跳过 
      dfs(nxtx,nxty);
    else//原来没有数字,枚举所有可能:填充1-9 
    {
        for(int j=1;j<=9;j++)
            if(check(x,y,j))
            {
                row[x][j]=col[y][j]=gr[group[x][y]][j]=1;
              sudoku[x][y]=j;
                dfs(nxtx,nxty);//搜索下一状态 
                sudoku[x][y]=0;//回溯,复原棋盘 
                row[x][j]=col[y][j]=gr[group[x][y]][j]=0;
          }
    }
}
int main()
{
    for(int i=0;i<9;i++)
      for(int j=0;j<9;j++)
      {
            int a;
            scanf("%d",&a);
            if(a==0) continue;
            row[i][a]=1;//第i行已有a 
            col[j][a]=1;//第j列已有a 
            gr[group[i][j]][a]=1;//i行j列所在区域 已有a 
            sudoku[i][j]=a;//填充入sudoku 
      }
    dfs(0,0);
    return 0;
}
View Code

 P1219

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int n;
int a[100];
int visited[3][100];
int count=0;
void dfs(int step){
    int i,j,flag;
    if(step==n+1){
        count++;
        if(count<=3){
            for(i=1;i<=n;i++)
                printf("%d ",a[i]);
            printf("\n");
        }
        return;
    }
    for(i=1;i<=n;i++){
        if(!visited[0][i]&&!visited[1][i+step]&&!visited[2][step-i+n]){
            visited[0][i]=visited[1][i+step]=visited[2][step-i+n]=1;
            a[step]=i;
            dfs(step+1);
            visited[0][i]=visited[1][i+step]=visited[2][step-i+n]=0;
        }
    }
}
int main(){
    memset(visited,0,sizeof(visited));
    scanf("%d",&n);
    dfs(1);
    printf("%d\n",count);
    return 0;
}
View Code

 

posted @ 2021-12-11 09:11  Oranges  阅读(146)  评论(0编辑  收藏  举报