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

时间很紧了,马上就要大三了。。 却还在低级算法遨游,说来真是忏愧,好好刷题了,两个寒假全浪费了

看到了一个同是大二,却比自己厉害很多的同龄人,自己需要加把劲了

加油!


[kuangbin带你飞]专题一 简单搜索 题解_第1张图片

A题 棋盘问题

直接dfs,枚举所有情况就行

代码如下

#include
#include
#include
#include
using namespace std;
char a[10][10];
int ans=0;
int n,k;
int visit [10];
void bfs(int cnt,int x,int y)
{
    if(cnt==k) {
        ans++;
        return ;
    }
    visit[y]=1;
    for(int i=x+1;i

B题

三维的bfs

代码如下

#include
#include
#include
#include
#include
using namespace std;
char a[35][35][35];
int l,r,c;
struct Node
{
    int x,y,z;
}s,e;
int xyz[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
void bfs()
{
    int visit[35][35][35];
    memset(visit,-1,sizeof(visit));
    queue q;
    q.push(s);
    visit[s.x][s.y][s.z]=0;
    while(!q.empty()) {
        Node temp=q.front();
        q.pop();
        for(int i=0;i<6;i++){
            int xx=temp.x+xyz[i][0];
            int yy=temp.y+xyz[i][1];
            int zz=temp.z+xyz[i][2];
            if(visit[xx][yy][zz]==-1&&(a[xx][yy][zz]=='.'||a[xx][yy][zz]=='E')) {
                Node n;
                n.x=xx; n.y=yy; n.z=zz;
                q.push(n);
                visit[xx][yy][zz]=visit[temp.x][temp.y][temp.z]+1;
            }
        }
        if(visit[e.x][e.y][e.z]!=-1) {
            printf("Escaped in %d minute(s).\n",visit[e.x][e.y][e.z]); return ;
        }
    }
    printf("Trapped!\n");
    return ;
}
int main()
{
    while(~scanf("%d%d%d",&l,&r,&c)) {
        if(l==0&&r==0&&c==0) {
            break;
        }
        for(int i=0;i

C题

最简单的bfs 入门题

#include
#include
#include
#include
#include
using namespace std;
int visit[100005];
int n,k;
void bfs()
{
   memset(visit,-1,sizeof(visit));
   queue q;
   visit[n]=0;
   q.push(n);
   while(!q.empty()){
        int temp=q.front();
        q.pop();
        if(temp+1<=100000&&visit[temp+1]==-1) {
            q.push(temp+1);
            visit[temp+1]=visit[temp]+1;
        }
        if(temp-1>=0&&visit[temp-1]==-1) {
            q.push(temp-1);
            visit[temp-1]=visit[temp]+1;
        }
        if(2*temp<=100000&&visit[2*temp]==-1) {
            q.push(2*temp);
            visit[2*temp]=visit[temp]+1;
        }
        if(visit[k]!=-1) {
            printf("%d\n",visit[k]); break;
        }
   }
}
int main()
{
    scanf("%d%d",&n,&k);
    bfs();
}

D题 翻转问题

直接暴力,是2^(n*m) 枚举第一行 n*m*2^n

代码如下

#include
#include
#include
#include
using namespace std;
int m,n;
int tile[20][20];
int ans[20][20];
int temp[20][20];
int dx[5]={-1,0,0,0,1};
int dy[5]={0,-1,0,1,0};
int get(int x,int y)
{
    int c=tile[x][y];
    for(int i=0;i<5;i++){
        int xx=x+dx[i],yy=y+dy[i];
        if(0<=xx&&xx>j&1;
        }
        int num=cal();
        if(num>=0&&(res<0||res>num)) {
            res=num;
            memcpy(ans,temp,sizeof(temp));
        }
    }
    if(res<0) {
        printf("IMPOSSIBLE\n");
    }
    else{
        for(int i=0;i
E题

bfs

 代码如下

#include
#include
#include
#include
#include
using namespace std;
void bfs(int n)
{
    queue q;
    q.push(1);
    while(!q.empty()) {
        long long temp=q.front();
        q.pop();
        if(temp%n==0) {
            printf("%lld\n",temp);
            break;
        }
        q.push(temp*10);
        q.push(temp*10+1);
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n)) {
        if(n==0) break;
        bfs(n);
    }
}
F题

打个表,枚举

代码如下

#include
#include
#include
#include
#include
using namespace std;
bool is_prime[10005];
void bfs(int a,int b)
{
    int visit[10005];
    memset(visit,-1,sizeof(visit));
    visit[a]=0;
    queue q;
    q.push(a);
    while(!q.empty()){
        int temp=q.front();
        int s=temp;
        q.pop();
        int num[4],cnt=0;
        while(temp){
            num[cnt++]=temp%10;
            temp/=10;
        }
        for(int i=0;i<=9;i++){
            if(i!=num[0]) {
                temp=num[3]*1000+num[2]*100+num[1]*10+i;
                if(is_prime[temp]&&visit[temp]==-1) {
                    q.push(temp);
                    visit[temp]=visit[s]+1;
                }
            }
        }
        for(int i=0;i<=9;i++){
            if(i!=num[1]) {
                temp=num[3]*1000+num[2]*100+i*10+num[0];
                if(is_prime[temp]&&visit[temp]==-1) {
                    q.push(temp);
                    visit[temp]=visit[s]+1;
                }
            }
        }
        for(int i=0;i<=9;i++){
            if(i!=num[2]) {
                temp=num[3]*1000+i*100+num[1]*10+num[0];
                if(is_prime[temp]&&visit[temp]==-1) {
                    q.push(temp);
                    visit[temp]=visit[s]+1;
                }
            }
        }
        for(int i=1;i<=9;i++){
            if(i!=num[3]) {
                temp=i*1000+num[2]*100+num[1]*10+num[0];
                if(is_prime[temp]&&visit[temp]==-1) {
                    q.push(temp);
                    visit[temp]=visit[s]+1;
                }
            }
        }
        if(visit[b]!=-1) {
            printf("%d\n",visit[b]); break;
        }
    }
}
int main()
{
    for(int i=0;i<=9999;i++)
        is_prime[i]=true;
    for(int i=2;i<=9999;i++){
        if(is_prime[i]) {
            for(int j=2*i;j<=9999;j+=i){
                is_prime[j]=false;
            }
        }
    }
    int t;
    scanf("%d",&t);
    while(t--){
        int a,b;
        scanf("%d%d",&a,&b);
        bfs(a,b);
    }
}

G题

读懂题就很简单

#include
#include
#include
#include
#include
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    int num=1;
    while(t--) {
        int len;
        scanf("%d",&len);
        map m;
        string s1,s2,s12;
        cin>>s1>>s2>>s12;
        printf("%d ",num++);
        int cnt=0;
        int flag=-1;
        while(true) {
            cnt++;
            string temp;
            int tt=0;
            while(tt
H题

bfs,6种状态,记录前面的状态

代码如下

#include
#include
#include
#include
#include
using namespace std;
int a,b,c;
int visit[105][105];
struct Node
{
    int A,B,step;
    int pa,pb;
}v[105][105],as;
string s[105];
int bfs()
{
    memset(visit,0,sizeof(visit));
    for(int i=0;i<=100;i++) {
        for(int j=0;j<=100;j++){
            v[i][j].pa=i; v[i][j].pb=j;
        }
    }
    queue q;
    v[0][0].A=0; v[0][0].B=0; v[0][0].step=0;
    visit[0][0]=1;
    q.push(v[0][0]);
    while(!q.empty()) {
        Node temp=q.front();
        q.pop();
        if(temp.A==c||temp.B==c) {
            as=temp;
            return temp.step;
        }
        if(temp.A!=a&&visit[a][temp.B]==0) {
            v[a][temp.B].A=a; v[a][temp.B].B=temp.B;
            v[a][temp.B].step=temp.step+1;
            v[a][temp.B].pa=temp.A; v[a][temp.B].pb=temp.B;
            visit[a][temp.B]=1;
            q.push(v[a][temp.B]);
        }
        if(temp.B!=b&&visit[temp.A][b]==0) {
            v[temp.A][b].A=temp.A; v[temp.A][b].B=b;
            v[temp.A][b].step=temp.step+1;
            v[temp.A][b].pa=temp.A; v[temp.A][b].pb=temp.B;
            visit[temp.A][b]=1;
            q.push(v[temp.A][b]);
        }
        if(temp.A!=0&&visit[0][temp.B]==0) {
            v[0][temp.B].A=0; v[0][temp.B].B=temp.B;
            v[0][temp.B].step=temp.step+1;
            v[0][temp.B].pa=temp.A;  v[0][temp.B].pb=temp.B;
            visit[0][temp.B]=1;
            q.push(v[0][temp.B]);
        }
        if(temp.B!=0&&visit[temp.A][0]==0) {
            v[temp.A][0].A=temp.A; v[temp.A][0].B=0;
            v[temp.A][0].step=temp.step+1;
            v[temp.A][0].pa=temp.A; v[temp.A][0].pb=temp.B;
            visit[temp.A][0]=1;
            q.push(v[temp.A][0]);
        }
        if((temp.A+temp.B>0&&temp.A+temp.B<=a)&&visit[temp.A+temp.B][0]==0) { //bµ¼Èëa
            v[temp.A+temp.B][0].A=temp.A+temp.B; v[temp.A+temp.B][0].B=0;
            v[temp.A+temp.B][0].step=temp.step+1;
             v[temp.A+temp.B][0].pa=temp.A;  v[temp.A+temp.B][0].pb=temp.B;
            visit[temp.A+temp.B][0]=1;
            q.push(v[temp.A+temp.B][0]);
        }
        if(temp.A+temp.B>a&&visit[a][temp.A+temp.B-a]==0) {              //bµ¼Èëa
           v[a][temp.A+temp.B-a].A=a; v[a][temp.A+temp.B-a].B=temp.A+temp.B-a;
           v[a][temp.A+temp.B-a].step=temp.step+1;
           v[a][temp.A+temp.B-a].pa=temp.A; v[a][temp.A+temp.B-a].pb=temp.B;
           visit[a][temp.A+temp.B-a]=1;
           q.push(v[a][temp.A+temp.B-a]);
        }
        if((temp.A+temp.B>0&&temp.A+temp.B<=b)&&visit[0][temp.A+temp.B]==0) {
            v[0][temp.A+temp.B].A=0; v[0][temp.A+temp.B].B=temp.A+temp.B;
            v[0][temp.A+temp.B].step=temp.step+1;
            v[0][temp.A+temp.B].pa=temp.A; v[0][temp.A+temp.B].pb=temp.B;
            visit[0][temp.A+temp.B]=1;
            q.push(v[0][temp.A+temp.B]);
        }
        if(temp.A+temp.B>b&&visit[temp.A+temp.B-b][b]==0) {
            v[temp.A+temp.B-b][b].A=temp.A+temp.B-b; v[temp.A+temp.B-b][b].B=b;
            v[temp.A+temp.B-b][b].step=temp.step+1;
            v[temp.A+temp.B-b][b].pa=temp.A; v[temp.A+temp.B-b][b].pb=temp.B;
            visit[temp.A+temp.B-b][b]=1;
            q.push(v[temp.A+temp.B-b][b]);
        }
    }
    return -1;
}
int main()
{

    while(~scanf("%d%d%d",&a,&b,&c)) {
        int ans=bfs();
        if(ans==-1) {
            printf("impossible\n");
        }
        else{
            printf("%d\n",ans);
            int k=0;
            while(1) {
                if(as.A==0&as.B==0) {
                    break;
                }
                Node pre=v[as.pa][as.pb];
                if(pre.A==as.A&&pre.B!=as.B) {
                    if(as.B==b) {
                        s[k++]="FILL(2)";
                    }
                    else{
                        s[k++]="DROP(2)";
                    }
                }
                 if(pre.A!=as.A&&pre.B==as.B) {
                    if(as.A==a) {
                        s[k++]="FILL(1)";
                    }
                    else{
                        s[k++]="DROP(1)";
                    }
                }
                if(pre.A+pre.B==as.A+as.B) {
                    if(as.A>=pre.A) {
                        s[k++]="POUR(2,1)";
                    }
                    else{
                        s[k++]="POUR(1,2)";
                    }
                }
                as=pre;
            }
            for(int i=k-1;i>=0;i--) {
                cout<
i题 任取两个点,求最短时间

#include
#include
#include
#include
#include
using namespace std;
int n,m;
 queue >q;
char s[15][15];
int visit[15][15];
int cnt=0;
int xy[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int bfs()
{
    int tem=0;
    int ans=0;
    while(!q.empty()) {
        pair temp=q.front();
        q.pop();
        tem++;
        for(int i=0;i<4;i++) {
            int dx=temp.first+xy[i][0];
            int dy=temp.second+xy[i][1];
            if(0<=dx&&dx
j题

先对fire进行bfs,再对f进行bfs

代码如下

#include
#include
#include
#include
#include
using namespace std;
int n,m;
char s[1005][1005];
int xy[4][2]={{1,0},{0,-1},{-1,0},{0,1}};
int visit1[1005][1005],visit2[1005][1005];
queue > q;
void bfs_fire()
{
    while(!q.empty()) {
        pair temp=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int dx=xy[i][0]+temp.first;
            int dy=xy[i][1]+temp.second;
            if(0<=dx&&dx temp=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int dx=xy[i][0]+temp.first;
            int dy=xy[i][1]+temp.second;
            int dev=visit2[temp.first][temp.second]+1;
            if(dx<0||dx>=n||dy<0||dy>=m) {
                return dev;
            }
            if(0<=dx&&dx

k题 水题

代码如下

#include
#include
#include
#include
#include
using namespace std;
int a[10][10];
int visit[10][10];
int xy[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
typedef pair p;
void bfs( )
{
    queue

q; memset(visit,-1,sizeof(visit)); q.push(make_pair(0,0)); visit[0][0]=0; while(!q.empty()) { p temp=q.front(); q.pop(); for(int i=0;i<4;i++){ int dx=temp.first+xy[i][0]; int dy=temp.second+xy[i][1]; if(0<=dx&&dx<5&&0<=dy&&dy<5&&visit[dx][dy]==-1&&a[dx][dy]==0) { q.push(make_pair(dx,dy)); visit[dx][dy]=visit[temp.first][temp.second]+1; } } if(visit[4][4]!=-1) { break; } } p a[100];int num=0; a[num].first=4; a[num].second=4; num++; int x=4,y=4; while(true) { for(int i=0;i<4;i++){ int dx=x+xy[i][0]; int dy=y+xy[i][1]; if(visit[x][y]-visit[dx][dy]==1) { a[num].first=dx; a[num].second=dy; num++; x=dx; y=dy; break; } } if(x==0&&y==0) { break; } } for(int i=num-1;i>=0;i--){ printf("(%d, %d)\n",a[i].first,a[i].second); } } int main() { for(int i=0;i<5;i++) for(int j=0;j<5;j++) scanf("%d",&a[i][j]); bfs(); }

L题

求联通块 bfs

代码如下

#include
#include
#include
#include
using namespace std;
char s[105][105];
int n,m;
int xy[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
void dfs(int x,int y)
{
    s[x][y]='*';
    for(int i=0;i<8;i++){
        int dx=x+xy[i][0];
        int dy=y+xy[i][1];
        if(0<=dx&&dx

M题

既可以是数论,也可以枚举6种状态 看的别人的代码,写的另一个类似的题

#include
#include
#include
using namespace std;
int v[5];
int sign[110][110][100];
struct cup//记录遍历中3个水杯容藏可乐情况
{
    int v[5];
    int step;
}temp;

void pour(int a,int b)//倒水函数,把a杯子中的可乐倒到b杯子中
{
    int sum=temp.v[a]+temp.v[b];
    if(sum>=v[b])
        temp.v[b]=v[b];
    else
        temp.v[b]=sum;
    temp.v[a]=sum-temp.v[b];
}

void bfs()
{
    int i,j;
    queueq;
    cup cnt;
    cnt.v[1]=v[1];
    cnt.v[2]=0;
    cnt.v[3]=0;
    cnt.step=0;
    q.push(cnt);
    memset(sign,0,sizeof(sign));
    sign[v[1]][0][0]=1;
    while(!q.empty())
    {
        cnt=q.front();
        q.pop();
        if(cnt.v[1]==cnt.v[3]&&cnt.v[2]==0)
        {
            printf("%d\n",cnt.step);
            return ;
        }
        for(i=1;i<4;++i)
        {
            for(j=1;j<4;++j)
            {
                if(i!=j)//自己不倒水给自己  
                {
                    temp=cnt;//每个水位情况都要把所有操作枚举一遍,所以都要赋值为原始水位情况  
                    pour(i,j);
                    if(!sign[temp.v[1]][temp.v[2]][temp.v[3]])
                    {
                        temp.step++;
                        q.push(temp);
                        sign[temp.v[1]][temp.v[2]][temp.v[3]]=1;
                    }
                }
            }
        }
    }
    printf("NO\n");
}

int main()
{
    while(scanf("%d%d%d",&v[1],&v[2],&v[3])&&v[1]||v[2]||v[3])
    {
        if(v[2]>v[3])
        {
            int t=v[2];
            v[2]=v[3];
            v[3]=t;
        }
        bfs();
    }
    return 0;
}

n题

求两个点到一个点的最短距离

代码如下

#include
#include
#include
#include
#include
using namespace std;
int n,m;
char s[205][205];
int xy[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
void bfs(int sx,int sy,int visit[][205])
{
    queue >q;
    q.push(make_pair(sx,sy));
    visit[sx][sy]=0;
    while(!q.empty()) {
        pair temp=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int dx=temp.first+xy[i][0];
            int dy=temp.second+xy[i][1];
            if(0<=dx&&dx












你可能感兴趣的:([kuangbin带你飞]专题一 简单搜索 题解)