[kuangbin带你飞]专题一 简单搜索

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 



454 / 1008 Problem A POJ 1321 棋盘问题

d.在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

s.dfs

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char cb[10][10];//棋盘
int col[10];//标记当前列是否有棋子
int ans,n,k;//ans 记录方案总数

void dfs(int row,int sum){//行,已放置的总数
    if(sum==k){//已摆放的棋子总数 等于 k
        ans++;
        return;
    }
    int i,j;
    for(i=row;i<n;i++){//遍历行,从没有放置棋子的row行开始遍历
        for(j=0;j<n;j++){//遍历列,从第一列开始遍历
            if(cb[i][j]=='#'&&!col[j]){//棋盘区域,并且当前列没有棋子
                col[j]=1;
                dfs(i+1,sum+1);//在下一行中寻找放置棋子的位置
                col[j]=0;//取消标记
            }
        }
    }
}
int main(){
    int i;
    while(~scanf("%d%d",&n,&k)){
        if(n==-1&&k==-1)break;
        ans=0;//方案总数
        memset(col,0,sizeof(col));//标记初始化
        memset(cb,'',sizeof(cb));//棋盘初始化
        for(i=0;i<n;i++)scanf("%s",cb[i]);
        dfs(0,0);//0行,已放置总数0个
        printf("%d
",ans);
    }
    return 0;
}
View Code

328 / 854 Problem B POJ 2251 Dungeon Master


335 / 1101 Problem C POJ 3278 Catch That Cow

d.起始位置N,目标位置K。

3种操作,当前+1、当前-1、当前*2

s.bfs

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int Ma=100000;
bool vis[Ma+1];//标记访问
int ti[Ma+1];//记录时间
int n,k;//农夫、牛的位置

void bfs(){//广搜
    int i,now,temp;
    queue<int>q;
    memset(ti,0,sizeof(ti));
    memset(vis,false,sizeof(vis));//初始化都未被访问
    q.push(n);//初始位置入队
    vis[n]=true;
    while(!q.empty()){
        now=q.front();
        q.pop();
        if(now==k){//判断在这,如果抓到牛了
            printf("%d
",ti[k]);
            return;
        }
        for(i=1;i<=3;i++){//枚举下一步的三种移动方案,x-1、x+1、2*x
            switch(i){
                case 1:temp=now-1;break;
                case 2:temp=now+1;break;
                case 3:temp=now+now;break;
            }
            if(!vis[temp]&&temp>=0&&temp<=Ma){//当前位置未被访问,且位置合法
                vis[temp]=1;//标记访问
                ti[temp]=ti[now]+1;//时间=当前位置时间+1
                q.push(temp);//位置入队
            }
        }
    }

}
int main(){
    while(~scanf("%d%d",&n,&k)){
        bfs();
    }
    return 0;
}
View Code

161 / 503 Problem D POJ 3279 Fliptile


247 / 526 Problem E POJ 1426 Find The Multiple

d.给出n,求一个n的倍数,这个倍数只含0或1

s.bfs

#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;

int main(){
    __int64 t,t2;
    int n,i;
    while(~scanf("%d",&n)&&n!=0){
        queue<__int64>q;//队列定义在循环内,每次就不用清空了
        q.push(1);//首位必须为1
        while(!q.empty()){
            t=q.front();
            q.pop();
            if(t%n==0){//找到了倍数,输出
                printf("%I64d
",t);break;
            }
            for(i=0;i<=1;i++){// 每次最后一位 加个0 或者 加个1
                t2=t*10+i;
                q.push(t2);
            }
        }
    }
    return 0;
}
View Code

205 / 330 Problem F POJ 3126 Prime Path

d.一个4位的素数到另外一个4位的素数,每次只能改变一位,改变后也必须是素数,求最少需要的步数。

s.bfs

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<math.h>
using namespace std;

const int Ma=11000;//覆盖所有的四位数
bool mark[Ma];//标记素数
int s[Ma];//记录步数
bool f[Ma];//标记访问
void sieve_prime(){//素数筛法
    memset(mark,true,sizeof(mark));
    mark[0]=mark[1]=false;
    int k=sqrt(Ma),i,j;
    for(i=2;i<k;i++)
        if(mark[i])
            for(j=i*i;j<Ma;j+=i)
                mark[j]=false;
}
int change(int x,int i,int j){//x的第i位数字 变为j
    if(i==1)return j*1000+(x%1000);//依次改变1-4位的数字
    if(i==2)return (x/1000)*1000+j*100+x%100;
    if(i==3)return (x/100)*100+j*10+x%10;
    if(i==4)return (x/10)*10+j;
}
int main(){
    sieve_prime();//先求出素数
    int t,x,y,ans,now,temp,i,j,flag;//
    scanf("%d",&t);//测试用例
    while(t--){
        memset(f,false,sizeof(f));//初始未访问
        ans=-1;
        flag=0;//标记是否找到路径
        scanf("%d%d",&x,&y);//起点 和终点
        queue<int>q;//队列定义在循环内,不用每次用的时候清空了
        q.push(x);//x入队
        now=s[x]=0;//初始当前步数、x的步数 为0
        f[x]=true;//x标记为访问
        while(!q.empty()){
            now=q.front();
            q.pop();
            if(now==y){//如果到达终点
                flag=1;//标记找到路径
                break;//退出循环
            }
            for(i=1;i<=4;i++){//第几位
                for(j=0;j<=9;j++){//变成几
                    if(!(j==0&&i==1)){//首位不能变为0
                        temp=change(now,i,j);
                        if(!mark[temp]||f[temp])continue;//不是素数,或已经访问过
                        s[temp]=s[now]+1;//下个位置的步数为 当前步数+1
                        f[temp]=true;//标记temp为访问
                        q.push(temp);//temp 入队
                    }
                }
            }
        }
        if(flag)printf("%d
",s[y]);
        else printf("Impossible
");
    }
    return 0;
}
View Code

143 / 305 Problem G POJ 3087 Shuffle'm Up
129 / 347 Problem H POJ 3414 Pots
141 / 463 Problem I FZU 2150 Fire Game
134 / 710 Problem J UVA 11624 Fire!
255 / 399 Problem K POJ 3984 迷宫问题
196 / 276 Problem L HDU 1241 Oil Deposits


177 / 408 Problem M HDU 1495 非常可乐

d. S 可乐的体积 , N 和 M是两个杯子的容量。这三个容器可以来回倒,求平分可乐的最少次数。

s.bfs

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int vist[105][105][105],a,b,c;//a b c->S 可乐的体积 , N 和 M是两个杯子的容量
struct node
{
    int a,b,c;//分别表示可乐瓶子,杯子1,杯子2它们里面的可乐体积
    int step;//步数
};
int sum=0;
void bfs()
{
    queue<node>q;
    memset(vist,0,sizeof(vist));
    node p1;
    p1.a=a;
    p1.b=0;
    p1.c=0;
    p1.step=0;
    q.push(p1);
    vist[p1.a][0][0]=1;
    while(!q.empty())
    {
        p1=q.front();
        q.pop();
        if((p1.a==a/2&&p1.b==a/2)||(p1.a==a/2&&p1.c==a/2)||(p1.b==a/2&&p1.c==a/2))
        {
            printf("%d
",p1.step);
            return;
        }
        //
        node p2;
        if(p1.a!=0)
        {//a倒入b
            if(p1.a>b-p1.b)
            {
                p2.a=p1.a-(b-p1.b);
                p2.b=b;
                p2.c=p1.c;
                p2.step=p1.step+1;
            }
            else
            {
                p2.a=0;
                p2.b=p1.b+p1.a;
                p2.c=p1.c;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                q.push(p2);
            }
        }

        if(p1.a!=0)
        {//a倒入c
            if(p1.a>c-p1.c)
            {
                p2.a=p1.a-(c-p1.c);
                p2.b=p1.b;
                p2.c=c;
                p2.step=p1.step+1;
            }
            else
            {
                p2.a=0;
                p2.b=p1.b;
                p2.c=p1.c+p1.a;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                q.push(p2);
            }
        }

        if(p1.b!=0)
        {//b倒入a
            if(p1.b>a-p1.a)
            {
                p2.b=p1.b-(a-p1.a);
                p2.a=a;
                p2.c=p1.c;
                p2.step=p1.step+1;
            }
            else
            {
                p2.b=0;
                p2.a=p1.a+p1.b;
                p2.c=p1.c;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                q.push(p2);
            }
        }

        if(p1.b!=0)
        {//b倒入c
            if(p1.b>c-p1.c)
            {
                p2.b=p1.b-(c-p1.c);
                p2.a=p1.a;
                p2.c=c;
                p2.step=p1.step+1;
            }
            else
            {
                p2.b=0;
                p2.a=p1.a;
                p2.c=p1.c+p1.b;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                q.push(p2);
            }
        }

        if(p1.c!=0)
        {//c倒入a
            if(p1.c>a-p1.a)
            {
                p2.c=p1.c-(a-p1.a);
                p2.a=a;
                p2.b=p1.b;
                p2.step=p1.step+1;
            }
            else
            {
                p2.c=0;
                p2.a=p1.a+p1.c;
                p2.b=p1.b;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                q.push(p2);
            }
        }

        if(p1.c!=0)
        {//c倒入b
            if(p1.c>b-p1.b)
            {
                p2.c=p1.c-(b-p1.b);
                p2.a=p1.a;
                p2.b=b;
                p2.step=p1.step+1;
            }
            else
            {
                p2.c=0;
                p2.a=p1.a;
                p2.b=p1.b+p1.c;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                q.push(p2);
            }
        }
    }
    printf("NO
");
}
int main()
{
    while(~scanf("%d%d%d",&a,&b,&c))
    {

        if(a==0&&b==0&&c==0){
            break;
        }

        if(a%2==1)
        {
            printf("NO
");
            continue;
        }

        bfs();
    }
    return 0;
}
View Code

182 / 577 Problem N HDU 2612 Find a way

原文地址:https://www.cnblogs.com/gongpixin/p/5360617.html