【三月】第一次课堂练习

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

#include<stdio.h>
int m,n;
int ans; 
int cell[105][105];
int vis[105][105];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
void dfs(int x,int y){
    vis[x][y]=1;
    for(int i=0;i<4;i++){
        int next_x = x+dx[i];
        int next_y = y+dy[i];
        if(cell[next_x][next_y] == 0 || vis[next_x][next_y]==1) continue;
        else dfs(next_x,next_y);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%1d",&cell[i][j]);//限制输入数字的位数 
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(vis[i][j]==0 && cell[i][j]!=0 ) { //以(i,j)为起点寻找同属同一细胞的点 
            dfs(i,j);
            ans++; 
            } 
        }
    }
    printf("%d",ans);
}
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

P1506

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

int a[501][501];
int x,y,ans,dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1};

//dx,dy数组用于遍历上、下、左、右四个位置
//下标为0的地方用0填充即可

void dfs(int n,int m)
{
    if(n<0||m<0||n>x+1||m>y+1||a[n][m]) return ;
    //边界,如果到建设图外面或者这里有障碍就返回,没法子让洪水灌进来
    a[n][m]=1; //染色
    for(int i=1;i<=4;i++)
        dfs(n+dx[i],m+dy[i]);
}

int main()
{
    scanf("%d%d",&x,&y);
    for(int i=1;i<=x;i++)
    {
        char ch[501];
        scanf("%s",ch);
        for(int j=1;j<=y;j++) 
        {
            if(ch[j-1]=='0') a[i][j]=0;
            else a[i][j]=1;
            //字符 -> 数字
        }
    }
    dfs(0,0); //染色,可以形象的理解为让洪水全部灌进来

    for(int i=1;i<=x;i++)
        for(int j=1;j<=y;j++)
            if(!a[i][j]) //如果这个点没有被水淹
                ++ans;
    
    printf("%d",ans);
    return 0;
}
View Code

P2392

#include<bits/stdc++.h>
using namespace std;
int Left,Right,minn,ans;
int s[5];
int a[21][5];
void search(int x,int y){
    if(x>s[y]){
        minn=min(minn,max(Left,Right));
        return;
    }
    Left+=a[x][y];
    search(x+1,y);
    Left-=a[x][y];
    Right+=a[x][y];
    search(x+1,y);
    Right-=a[x][y];
}
int main(){
scanf("%d%d%d%d",&s[1],&s[2],&s[3],&s[4]);
    for(int i=1;i<=4;i++){
        Left=Right=0;
        minn=19260817;
        for(int j=1;j<=s[i];j++)
            scanf("%d",&a[j][i]);
        search(1,i);
        ans+=minn;
    }
    printf("%d",ans);
    return 0;
}
View Code

 

posted @ 2022-03-25 10:32  Oranges  阅读(34)  评论(0编辑  收藏  举报