搜索题解

Prime Path (BFS)


题意: 求一个素数 a 变换到 一个素数b 的最小次数

变换规则为:变换数的一个数位,然后使得变换后的数为素数;


思路: 这个能想到用bfs真是神奇,先把一个数的数位用一个数组记录,然后对其中的一个数位进行更改,然后判断更改后的数是否为素数,是的话入队;

          因为一次只能对一个数位进行操作,所以每次进行更改位上的数的时候记录一下,之后再放回去;


#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
const ll maxn =  10000 + 10;
#define INF 0x3f3f3f3f
int step[maxn];
bool vis[maxn];
bool is_prime[maxn];
void Init()
{
    memset(is_prime,true,sizeof(is_prime));
    is_prime[0] = is_prime[1] = false;
    for(int i = 2; i < maxn; i ++)
    {
        for(int j = i *2; j < maxn ; j += i)
        {
            is_prime[j] = false;
        }
    }
}
int bfs(int a,int b)
{
    memset(step,0,sizeof(step));
    memset(vis,false,sizeof(vis));
    queue<int>q;
    q.push(a);
    vis[a] = true;
    step[a] = 0;
    while(!q.empty())
    {
        int temp = q.front();
        if(temp == b)
        {
            return step[temp];
        }
        q.pop();
        int t[4];
        t[0] = temp/1000;
        t[1] = temp/100 % 10;
        t[2] = temp/10 %10;
        t[3] = temp % 10;
//        cout << t[0] << " " << t[1] << " " << t[2] << " " << t[3] << endl;
        for(int i = 0; i < 4; i ++)
        {
            int ts = t[i];
            for(int j = 0; j <= 9; j ++)
            {
                if(j == temp)
                    continue;
                t[i] = j;
                int tss = t[0] * 1000 + t[1] * 100 + t[2] * 10 + t[3];
                if(!vis[tss]  && t[0] != 0 && is_prime[tss])
                {
                    q.push(tss);
                    vis[tss] = true;
                    step[tss] = step[temp] + 1;
                }
            }
            t[i] = ts;
        }
    }
    return -1;
}
int main()
{
    Init();
    int n;
    while( ~ scanf("%d",&n))
    {
        while( n --)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            int ans = bfs(a,b);
            if(ans == -1)
            {
                cout << "Impossible" << endl;
            }
            else cout << ans << endl;
        }
    }
    return 0;
}


棋盘问题:poj1321(DFS)

题意: 在n * n的棋盘的空白位置放入 m 个棋子,要求每个棋子的行列不相同;

思路: 数据量非常小,n < 8;

所以用结构体存一下空白位置的坐标,然后进行搜索就行了;

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn =  10 + 10;
char s[maxn][maxn];
struct Node
{
    int x,y;
}a[maxn * maxn];
bool visx[maxn];
bool visy[maxn];
int n,m;
int ans;
int len;
void dfs(int length,int k)
{
    if(length == m)
    {
        ans ++;
        return;
    }
    for(int i = k; i < len ; i ++)
    {
      if(!visx[a[i].x] && !visy[a[i].y])
      {
          visx[a[i].x] = visy[a[i].y] = true;
          dfs(length + 1,i);
          visx[a[i].x] = visy[a[i].y] = false;
      }
    }
}
int main()
{
    while( ~ scanf("%d%d",&n,&m) && !(n == -1 && m == -1))
    {
        ans = 0;
        memset(visx,false,sizeof(visx));
        memset(visy,false,sizeof(visy));
        len = 0;
        for(int i = 0; i < n ; i ++)
        {
            scanf("%s",s[i]);
            for(int j = 0; j < n; j ++)
            {
                if(s[i][j] == '#')
                {
                    a[len].x = i;
                    a[len ++].y = j;
                }
            }
        }

        if(len < m)
        {
            cout << 0 << endl;
            continue;
        }
//        cout << len << " " << m << endl;
        dfs(0,0);
        cout << ans << endl;

    }
    return 0;
}

Find The Multiple
 dfs

题意: 找到能整除n 的的十进制数m, 并且m 数位上的数只由0,1组成;

#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<map>
using namespace std;
typedef unsigned long long ll;
const ll maxn =  100 + 10;
#define INF 0x3f3f3f3f
bool flag;
void dfs(ll m,ll n,ll k)
{
    if(flag)
        return;
    if(m % n == 0)
    {
        flag = true;
        cout << m <<endl;
        return;
    }
    if(k == 19)
    {
        return;
    }
    dfs(m * 10,n,k + 1);
    dfs(m * 10 + 1,n,k + 1);
}
int main()
{
    int n;
    while( ~ scanf("%d",&n) && n)
    {
        flag = false;
        dfs(1,n,0);
    }
}

Shuffle'm Up poj 3087 (BFS)


题意:

给定长度都为C两个字符串,S1,S2,和一个要求的结果字符串S12。先把 S2 的最下面一张牌放在最下面,然后S1,S2交错的叠放,得到新的S12,再把S12最下面的C个字符赋值给S1,把剩下的赋值给S2,再次重复上面的过程。最后求出要得到目标字符串S,问最少需要几步。

注意:

题目所给出的输入是从低向上排列的。

解析:

简单的bfs问题,直接模拟就好了。

#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
const ll maxn =  10000 + 10;
#define INF 0x3f3f3f3f
map<string,int>vis,tt;
int bfs(string s1,string s2,string s12)
{
    queue<string>q;
    string ss;
    int len = s1.length();
    for(int i = 0; i < len; i ++)
    {
        ss += s2[i];
        ss += s1[i];
    }
    vis[ss] = 1;
    tt[ss] = 1;
    q.push(ss);
    while(!q.empty())
    {
        string t = q.front();
        q.pop();
        if(t == s12)
        {
            return tt[t];
        }
        string ss1 ,ss2 ,ss3;
        for(int i = 0; i < len; i ++)
            ss1 += t[i];
        for(int i = len; i < len * 2; i ++)
            ss2 += t[i];
        for(int i = 0; i < len; i ++)
        {
            ss3 += ss2[i];
            ss3 += ss1[i];
        }
        if(!vis[ss3])
        {
            tt[ss3] = tt[t] + 1;
            q.push(ss3);
            if(ss3 == s12)
            {
                return tt[ss3];
            }
        }
    }
    return -1;
}
int main()
{
    int Tcase;
    scanf("%d",&Tcase);
    for(int ii = 1; ii <= Tcase; ii ++)
    {
        vis.clear();
        tt.clear();
        int n;
        scanf("%d",&n);
        string s1,s2,s12;
        cin >> s1 >> s2 >> s12;
        int ans = bfs(s1,s2,s12);
        cout << ii << " " << ans << endl;
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值