搜索——DFS之搜索顺序

马走日

原题链接

这里是引用

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define int long long
#define fi first
#define se second
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef pair<int, int>pii;

const int N =12 ;
int n,m,sx,sy;
int ans;
bool st[N][N];
int dx[8]={-2,-2,-1,1,2,2,1,-1},dy[8]={-1,1,2,2,1,-1,-2,-2};

void dfs(int x,int y,int sum){
    if(sum==n*m){
        ans++;
        return;
    }
    st[x][y]=true;
    for(int i=0;i<8;i++){
        int a=x+dx[i],b=y+dy[i];
        if(a<0||a>=n||b<0||b>=m) continue;
        if(st[a][b]) continue;
        dfs(a,b,sum+1);//不要用sum++,因为sum要复原,不走这个格子后sum要-1
    }
   st[x][y]=false;
   
}
signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int k;
    cin>>k;
    while(k--){
        cin>>n>>m>>sx>>sy;
        ans=0;
        memset(st,0,sizeof st);
        dfs(sx,sy,1);
        cout<<ans<<endl;
    }

    return 0;
}

debug

  1. 马走日的dx和dy定义问题
  2. sum复原问题,不要sum++,不然不会复原。

单词接龙

原题链接

这里是引用

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define int long long
#define fi first
#define se second
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef pair<int, int>pii;

const int N = 25;
int n;
string s[N];
int cnt[N];
int ans=0;
void dfs(string t,int last){
    // cnt[last]++;
    int len=t.size();
    ans=max(ans,(long long)t.size());
    for(int i=0;i<n;i++){
        for(int j=1;j<min(s[last].size(),s[i].size());j++){
            if(cnt[i]<2&&t.substr(t.size()-j)==s[i].substr(0,j)){
                string state=t+s[i].substr(j);
                cnt[i]++;
                dfs(state,i);
                cnt[i]--;
            }
        }
        // for(int j=len-1,k=1;j>0&&k<s[i].size();j--,k++){
        //     if(cnt[i]<2&&t.substr(j)==s[i].substr(0,k)){
        //         string state=t.substr(0,len-k)+s[i];
        //         dfs(state,i);
        //     }
        // }
    }
    // cnt[last]--;
}
signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin>>n;
    for(int i=0;i<n;i++) cin>>s[i];
    string ch;//不要用char,不然读入的是回车
    cin>>ch;
    s[n]=" "+ch;
    dfs(s[n],n);
    cout<<ans-1;
    return 0;
}

debug

最后一个开头的字母,不要用char来读入,不然会读回车的。用string,yyds

分成质数组

原题链接

这里是引用

思路一

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define int long long
#define fi first
#define se second
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef pair<int, int>pii;

const int N = 12;
int n;
int a[N],ans=10,len=0;//这里不能先赋值ans
vector<int> g[N];

int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
void dfs(int u){
    if(u==n){
        ans=min(ans,len);
        return;
    }
    
    for(int i=0;i<len;i++){
    	bool flag=false;//放for循环里面,呜呜呜
        for(int j=0;j<g[i].size();j++){
            if(gcd(a[u],g[i][j])>1){
                flag=true;
                break;
            }
        }
        if(!flag){
            g[i].push_back(a[u]);
            dfs(u+1);
            g[i].pop_back();
        }
    }
    g[len++].push_back(a[u]);
    dfs(u+1);
    g[--len].pop_back();
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    dfs(0);
    cout<<ans;
    return 0;
}

为每个数找到适合的组放进去,或者重新开一个放进去。

debug

flag要放for循环里面,不然就只能用一次,那个是判断a[u]是否能放在第i组里面

思路二

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define int long long
#define fi first
#define se second
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef pair<int, int>pii;

const int N = 10;
int n;
int a[N];
int ans=N;
int g[N][N];
int st[N];

int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
bool check(int g[],int x,int start){
    for(int i=0;i<start;i++)
        if(gcd(g[i],x)>1) return false;
    return true;
}
//gr当前组数,并放在g[gr]数组里面
//gc表示g[gr]里面元素个数,也即目前点放的位置(0开始)
//start表示从那个数开始放入此数组
//当前已经放入数组的个数(完成分组)
void dfs(int gr,int gc,int start,int cnt){
    if(gr>=ans) return;
    if(cnt==n) ans=gr;
    bool flag=true;
    for(int i=start;i<n;i++){
        if(!st[i]&&check(g[gr],a[i],gc)){
            st[i]=true;
            g[gr][gc]=a[i];
            dfs(gr,gc+1,i+1,cnt+1);
            st[i]=false;
            flag=false;
        }
    }
    if(flag) dfs(gr+1,0,0,cnt);
}
signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    dfs(1,0,0,0);
    cout<<ans;

    return 0;
}

每次从前往后扫描,将互质的数都装进一个组。每次扫描结束后都重新开一个组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值