dfs练习题及代码(原创)(c++)

一,西红柿炸弹

# include <bits/stdc++.h>
using namespace std;
bool a[600][600];
//int dist[1000][1000];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
//0 右  1 下
int n,m;
int j;
void boom(int xx,int yy,int l,int r,int u,int d){
    int p=1,s=1;
    int x=xx;
    int y=yy;
    a[x][y]=1;
    while((x+p)<=n&&p<=d){
        a[x+p][y]=1;
        p++;
    }
    p=1;
    while((x-p)>0&&p<=u){
        a[x-p][y]=1;
        p++;
    }
    while((y+s)<=m&&s<=r){
        a[x][y+s]=1;
        s++;
    }
    s=1;
    while((y-s)>0&&s<=l){
        a[x][y-s]=1;
        s++;
    }
}
void search(int x,int y){
        if (j==1||(x == n && y == m)) {
            j = 1;
            return;
        } else {
            for (int i = 0; i <=3; i++) {
                int xx = 0, yy = 0;
                xx = x + dx[i], yy = y + dy[i];
                if (xx <= n && xx > 0 && yy <= m && yy > 0 && a[xx][yy] == 0) {
                    a[x][y] = 1;
                    search(xx, yy);
                }
            }
        }
}

int main(){
    int t;
    cin>>t;
    while(t--){
        j=0;
        scanf("%d %d",&n,&m);
        memset(a,0,sizeof(a));
        int k;
        cin>>k;
        while(k--){
            int b,c,d,e,f,g;
            scanf("%d %d %d %d %d %d",&b,&c,&d,&e,&f,&g);
            boom(b,c,d,e,f,g);
        }
        int yn=0;
        if(a[1][1]==1||a[n][m]==1){printf("no\n");yn=1;}
        if(yn==0) {
            search(1, 1);
            if (j == 0)printf("no\n");
            else printf("yes\n");
        }
    }
}//
// Created by 17987 on 2024/11/4.
//

二,密码

# include <bits/stdc++.h>
using namespace std;
long long ans;
int a[5];
int n;
int cnt;
void search(int c,long long sum){
    if(n==1){
        if(a[0])cnt++;
        if(a[3])cnt++;
        return;
    }
    while(c==n){
        if(sum%3==0) {
            cnt++;
        }
        return;
    }
    if(c==0){
        for(int i=1;i<=4;i++){
            if(a[i]){
                a[i]--;
                search(c+1,sum+i);
                a[i]++;
            }
        }
    }
    else {for(int i=0;i<=4;i++){
        if(a[i]){
            a[i]--;
            search(c+1,sum+i);
            a[i]++;
        }
    }}
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        cnt=0;
        memset(a,0,sizeof(a));
        for(int i=0;i<5;i++){
            scanf("%d",&a[i]);
        }
        scanf("%d",&n);
        search(0,0);
        printf("%d\n",cnt);
    }
}//
// Created by 17987 on 2024/11/4.
//

三,逃出峡谷

要注意x<=nn+1,且瞬间移动不能超过nn。因为这个重写了2次。 

# include <bits/stdc++.h>
using namespace std;
int dist[200000+10];
int nn;
float dx[3]={2,0.4,-1};
float dy[3]={1,1.5,1};
void search(){
    dist[0]=1;
    dist[1]=0;
    queue<int> q;
    q.push(1);
    while(q.size()){
        int t = q.front();
        int n;
        q.pop();
        for(int i=0;i<3;i++) {
            n = (int)((t+dx[i])*dy[i]);//1 前进两个 3 后退1个 2前进1.5步
            if(i==1&&n>nn)continue;
            if (n<=nn+1&&n>0&&(dist[n] > dist[t] + 1)) {
                dist[n] = dist[t] + 1;
                q.push(n);
            }
        }
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        memset(dist,0x3f,sizeof(dist));
        scanf("%d",&nn);
        search();
        printf("%d\n",dist[nn]);
    }
}//
// Created by 17987 on 2024/11/4.
//

四,突破

 

s不用重复走。

# include <bits/stdc++.h>
using namespace std;
int n,m,k;
char a[20][20];//地图
int vis[20][20];//步数
int gg[20][20];//功力
int max1=-1;
#define  pii pair<int,int>
int q1,q2,w1,w2;
pii hs[20][20];
int dx[8] = {1, -1, 0, 0, 1, 1, -1, -1};
int dy[8] = {0, 0, 1, -1, 1, -1, 1, -1};
//0 you  3 xia
int yun(int x,int y){
    int sum=0;
    for(int i=1;i<=3;i++){
        if(vis[x-1][y-2+i])sum++;
        if(vis[x+1][y-2+i])sum++;
        if(vis[x][y-2+i])sum++;
    }
    if(abs(x-q1)<=1&&abs(y-q2)<=1){
        sum--;
    }
    return sum;
}
void hss(int x,int y){//回溯
    int i=x,j=y;
    while(hs[i][j]!= make_pair(q1,q2)){
        int xx =hs[i][j].first;
        int yy = hs[i][j].second;
        i=xx;
        j=yy;
        cout<<"("<<i<<","<<j<<") ";
    }
}
void search(int kk,int xx,int yy,int gg,int w){
    if(xx==w1&&yy==w2){
            //cout<<" gg "<<gg<<": ";
            //hss(xx,yy);
            //cout<<"kk"<<kk<<endl;
            max1 = max(max1,gg);
        return;
        }
        vis[xx][yy]=1;
        for(int i=0;i<=3;i++) {
            int x = xx + dx[i];
            int y = yy + dy[i];
            if (vis[x][y])continue;
            if (kk - w == k && a[x][y] != 'L' && a[x][y] != 'W')continue;
            if(x<1||x>n||y<1||y>m)continue;
                hs[x][y] = {xx, yy};
                if (a[x][y] <= '9' && a[x][y] >= '0') {
                    search(kk + 1, x, y, gg + a[x][y] - '0', w);
                } else if (a[x][y] == 'Y') {
                    int cnt = 0;
                    for (int j = 0; j < 8; j++) {
                        int nnx = x + dx[j];
                        int nny = y + dy[j];
                        if (nnx < 1 || nnx > n || nny < 1 || nny > m) continue;
                        if (vis[nnx][nny] && a[nnx][nny] != 'S') {
                            cnt++;
                        }
                    }
                    search(kk + 1, x, y, gg + cnt, w);
                } else if (a[x][y] == 'Z') {
                    search(kk + 1, x, y, gg + kk + 1, w);
                } else if (a[x][y] == 'L') {
                    search(kk + 1, x, y, gg, w + 1);
                } else if (a[x][y] == 'W') {
                    search(kk + 1, x, y, gg, w + 2);
                } else if (a[x][y] == 'E') {
                    search(kk + 1, x, y, gg, w);
                }
        }
        vis[xx][yy]=0;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        memset(vis,0,sizeof(vis));
        memset(gg,0,sizeof(gg));
        scanf("%d %d %d", &n, &m, &k);
        max1=-1;
        getchar();
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                scanf("%c", &a[i][j]);
                if (a[i][j] == 'S') { q1=i,q2=j; }
                if (a[i][j] == 'E') { w1=i,w2=j; }
            }
            getchar();
        }
        search(0,q1,q2,0,0);
        printf("%d\n", max1);
    }
}//
// Created by 17987 on 2024/11/4.
//

西瓜数

#include<iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
int n;
int a[10];
bool st[20];
string s1;
long long ans;
int min1=0x3f3f3f3f;
vector<vector<char>>vv;
void find(int t,vector<char>v,int n1){
    bool ynn=1;
    int x=0;
    if(t==8){
        memset(st,0,sizeof(st));
        for(auto it:v){
            int u=it-'0';
            x+=u*u;
            st[u]=1;
        }
        for(int i=1;i<=9;i++){
            if(st[i]){
                if(x%i==0)continue;
                ynn=0;
            }
        }
        if(ynn){vv.push_back(v);}
        return;
    }
    for(int i=n1;i<=9;i++){
        v.push_back(i+'0');
        find(t+1,v,i);
        v.pop_back();
    }
}
void al(string s){
    if(min1<=1)return;
    s=' '+s;
    int sum;
    for(int i=0;i<8;i++){
        sum+=abs(s1[i]-s[i]);
    }
    min1=min(min1,sum);
}

void watermelon(string s){
    vector<char>v1;
    for(int i=0;i<8;i++){
        v1.push_back(s[i]);
    }
    for(auto u:vv){
        int dis=0;
        int cnt=0;
        for(auto it:u){
            dis+=abs(it-s[cnt]);
            cnt++;
        }
        min1=min(min1,dis);
        if(min1==0)return;
    }
}
int main(){
    scanf("%d",&n);
    vector<char>v;
    find(0,v,1);
    for(int i=1;i<=n;i++){
        min1=0x3f3f3f3f;
        ans=0;
        memset(a,0,sizeof(a));
        string s;
        cin>>s;
        int len=s.length();
        if(len<=8){
            s1=s;
            for(int ii=1;ii<=8-len;ii++){
                s1='0'+s1;
            }
        }
        else {
            s=' '+s;
            s1 = s.substr(len - 7, len);
            for(int j=1;j<=len-8;j++){
                ans+=s[j]-'0';
            }
        }
        sort(s1.begin(),s1.end());
        watermelon(s1);
        cout<<ans+min1<<endl;
    }
}

 后续会持续更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值