2初出茅庐--初级篇2.1

 

DFS
KEY WORD:  盲搜    递归    遍历所有状态  栈(隐式利用)
/**
1.部分和问题
给定整数 a1 a2 …… an 判断是否可以从中选出若干数,使得他们的和等于k
n大于等于1 小于等于20
ai和k范围:-10^8 10^8

此类题,拒绝暴力
*/


#include "cstdio"
#define N 25
int a[N];
int n,k;

///从前i项得到了和sum,然后对i项之后的进行分支
bool dfs(int i,int sum)
{
    ///n项都计算过,返回sum和k是否相等
    if(i==n)return sum==k;
    ///不加上a[i]
    if(dfs(i+1,sum))return true;
    ///加上
    if(dfs(i+1,sum+a[i+1])) return true;
    ///无论加不加上都不能构成
    return false;
}
void solve()
{
    if(dfs(0,0))
        printf("Yes\n");
    else
        printf("No\n");
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        scanf("%d",&k);
        solve();
    }
    return 0;
}

4
1 2 4 7
13

4
1 2 4 7
15

Yes

No

积水问题:求水洼个数(8连通的积水认为连通)

#include "cstdio"
#define N 100
char field[N][N];
int n,m;
void dfs(int x,int y)
{
    if(x<0||y<0||x>=n||y>=m)return;
    if(field[x][y]=='w'){
        field[x][y]='.';
        for(int i=-1;i<=1;i++)
        {
            for(int j=-1;j<=1;j++){
                int nx=x+i,ny=y+j;
                dfs(nx,ny);
            }
        }
    }
    else
        return;
}
void solve()
{
    int cnt=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(field[i][j]=='w')
            {
                dfs(i,j);
                cnt++;
            }
        }
    }
    printf("%d\n",cnt);
}
int main()
{
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<n;i++)
            scanf("%s",field[i]);
        solve();
    }
    return 0;
}

 

BFS
KEY WORD:队列 近->远遍历
容易用来求,最短路径,最少操作之类问题
key  状态   转移方式

/**
1.迷宫的最短路径问题
# . S G
墙壁 通道 起点 终点

*/
#include "iostream"
#include "cstdio"
#include "queue"
using namespace std;
#define MAX 110
const int INF=100000000;
typedef pair<int,int>P;///状态

char maze[MAX][MAX];///迷宫
int d[MAX][MAX];///起点到各个位置最短距离的数组
int N,M;
int sx,sy;///地点 坐标
int gx,gy;///终点
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
int bfs()
{
    queue<P> que;
    ///INIT
    for(int i=0;i<N;i++)
        for(int j=0;j<M;j++)
        d[i][j]=INF;

    que.push(P(sx,sy));///起点
    d[sx][sy]=0;
    while(que.size())
    {
        P p=que.front();
        que.pop();
        if(p.first==gx&&p.second==gy)break;///到达终点

        for(int i=0;i<4;i++)///4方向
        {
            int nx=p.first+dx[i],ny=p.second+dy[i];
            if(0<=nx&&nx<N&&0<=ny&&ny<M&&maze[nx][ny]!='#'&&d[nx][ny]==INF)///可以移动吗?
            {
                que.push(P(nx,ny));///可移动,将点加入队列,长度加一
                d[nx][ny]=d[p.first][p.second]+1;
            }
        }
    }
    return d[gx][gy];
}
void solve()
{
    int res=bfs();
    printf("%d\n",res);
}

int main()
{
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    while(~scanf("%d%d",&N,&M))
    {
        for(int i=0;i<N;i++)
            scanf("%s",maze[i]);
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<M;j++)
            {
                if(maze[i][j]=='S')
                    sx=i,sy=j;
                if(maze[i][j]=='G')
                    gx=i,gy=j;
            }
        }
        solve();
    }
    return 0;
}

10 10
#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#

22

posted @ 2017-03-30 00:04  kimsimple  阅读(214)  评论(0编辑  收藏  举报