专题一 简单搜索

专题一 简单搜索


所有题目传输门

A - 棋盘问题 POJ - 1321

思路

  1. 数据范围 n <= 8, 可以用dfs暴力求解方案数,在dfs 的过程 要注意标记 行 和 列 、以及在回溯的过程中解除标记,还有 在dfs 的时候要注意 避免 重复递归 一些已经递归过的的 情况(在代码中的提现就是修改 每次 递归for的初始化条件)

代码

#include<cstring>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
#include<iostream>
#include<algorithm>
using namespace std;
const int mxn = 10;
int n, k;
char mz[mxn][mxn];
int lin[mxn], row[mxn];

int dfs(int ct, int l)
{
    if(ct == k)
        return 1;

    int sm = 0;
    for(int i = l; i <= n; i ++)
    {
        if(row[i]) continue;
        for(int j = 1; j <= n; j ++)
        {
            if(lin[j]) continue;
            if(mz[i][j] == '.') continue;
            row[i] = 1, lin[j] = 1;
            sm += dfs(ct + 1, i + 1);
            row[i] = 0, lin[j] = 0;
        }
    }
    return sm;
}

int main()
{
    /* fre(); */
    while(scanf("%d %d", &n, &k) && n != -1)
    {
        memset(lin, 0, sizeof(lin));
        memset(row, 0, sizeof(row));
        for(int i = 1; i <= n; i ++)
            scanf("%s", mz[i] + 1);
        printf("%d\n", dfs(0, 1));
    }

    return 0;
}

B - Dungeon Master POJ - 2251

思路

  1. 二维迷宫问题变形。。。

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
using namespace std;

const int mxn = 35;
int n, k;
char mz[mxn][mxn][mxn];
int mk[mxn][mxn][mxn];
int x, y, z;
struct Node
{
    int x, y, z, t;
    bool operator == (const Node T) const
    {
        if(T.x == x && T.y == y && T.z == z)
            return true;
        return false;
    }
} S, E;

Node mov[6] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { -1, 0, 0 }, { 0, -1, 0 }, { 0, 0, -1 } };

bool good(Node p)
{
    if(p.x >= 1 && p.y >= 1 && p.z >= 1 && p.x <= x && p.y <= y && p.z <= z && mz[p.z][p.x][p.y] != '#' && ! mk[p.z][p.x][p.y])
        return true;
    return false;
}



int tim;
bool dfs(Node P, int t)
{
    int fg = 0;
    if(P == E)
    {
        tim = min(tim, t);
        fg = 1;
    }

    for(int i = 0; i < 6; i ++)
    {
        Node now = { P.x + mov[i].x, P.y + mov[i].y, P.z + mov[i].z };
        if(! good(now)) continue;
        mk[now.z][now.x][now.y] = 1;
        if(dfs(now, t + 1)) fg = 1;
        mk[now.z][now.x][now.y] = 0;
    }

    if(fg) return true;
    return false;
}

int sp = INF;
bool bfs()
{
    queue<Node> q; 
    S.t = 0;
    q.push(S);
    while(! q.empty())
    {
        S = q.front(); q.pop();
        if(S == E)
        {
            sp = S.t;
            return true;
        }

        for(int i = 0; i < 6; i ++)
        {
            Node now = { S.x + mov[i].x, S.y + mov[i].y, S.z + mov[i].z, S.t + 1 };
            if(! good(now)) continue;
            mk[now.z][now.x][now.y] = 1;
            q.push(now);
        }
    }
    return false;
}



int main()
{
    /* fre(); */
    while(scanf("%d %d %d", &z, &x, &y) && x)
    {
        memset(mk, 0, sizeof(mk));
        tim = INF;
        sp = INF;
        for(int i = 1; i <= z; i ++)
        {
            for(int j = 1; j <= x; j ++)
            {
                scanf("%s", mz[i][j] + 1);
                for(int k = 1; k <= y; k ++)      
                {
                    if(mz[i][j][k] == 'S')
                        S.z = i, S.x = j, S.y = k;
                    if(mz[i][j][k] == 'E')
                        E.z = i, E.x = j, E.y = k;
                }
            }
        }

        mk[S.z][S.x][S.y] = 1;
        if(bfs())
            printf("Escaped in %d minute(s).\n", sp);
        else
            printf("Trapped!\n");
    }

    return 0;
}


C - Catch That Cow POJ - 3278

思路

  1. 这一题用bfs去求解,从出位置s向终点e,逐渐广度搜索,对于某个位置x进行转移的时候可以,对其进行3种位置转移操作,
    1. 令 x -= 1
    2. 令 x+=1
    3. 令x*=2
      通过这三种操作可以令x的位置扩展到下一个位置, 注意对原来的已经扩展到的位置进行 标记。
  • 复杂度:O(n)

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
using namespace std;

const int mxn = 2e6 + 10;
int n, k;
struct Node
{
    int x, t;
};

int mk[mxn];

int check(int x)
{
    if(x<0 || x>=mxn || mk[x])
        return 0;
    return 1;
}


int bfs()
{
    mk[n] = 1; 
    queue<Node> q;
    q.push((Node){ n, 0 });
    while(! q.empty())
    {
        Node now = q.front(); q.pop();
        if(now.x == k) return now.t;

        if(check(now.x + 1))
        {
            mk[now.x + 1] = 1;
            q.push((Node){ now.x + 1, now.t + 1 });
        }

        if(check(now.x - 1))
        {
            mk[now.x - 1] = 1;
            q.push((Node){ now.x - 1, now.t + 1 });
        }
        if(check(now.x * 2))
        {
            mk[now.x * 2] = 1;
            q.push((Node){ now.x * 2, now.t + 1 });
        }
    }
}


int main()
{
    /* fre(); */
    while(scanf("%d %d", &n, &k) != EOF)
    {
        memset(mk, 0, sizeof(mk));
        int ans = bfs();
        printf("%d\n", ans);
    }

    return 0;
}


D - Fliptile POJ - 3279

思路

  1. 补充
  • 对于 某个位置我们最多只需要反转1次,因为反转2次的话有反转回去了
  • 不同位置反转的先后顺序并不改变最终的结果
  1. 这一题的 主要思路是,我们用 暴力的枚举 确定第一行的 哪些位置反转、哪些位置不反转(实际上我们用二进制枚举优化的 一下枚举的情况,但是本质还是暴力枚举),
  2. 对于我们枚举的一种的情况:我们已经(通过暴力枚举)确定了第一行对应位置的反转情况,在这个基础上 我们讨论第 2行的某个位置mz[2][j]的反转情况,我们考虑如果,在第一行中mz[1][j] == 1,那么我们一定要在mz[2][j]这个位置进行反转,如果不反转的话以后就没有机会反转了,,,,
  3. 同理我们在第2行的反转的情况的基础上讨论第3行的反转情况。。。。这样一直讨论的最后一行的反转情况就行了,
  4. 最后我们检查 最后一行的位置中的所有字符 如果都是 mz[n][1~m] 都为0的话这种的枚举方案是成立的,之后维护一下答案的就行了

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
using namespace std;

const int mxn = 20;
int n, m;
int ar[mxn][mxn], br[mxn][mxn];
int op[mxn][mxn], ans[mxn][mxn];
void turn(int x, int y)
{
    br[x][y] ^= 1; 
    br[x - 1][y] ^= 1; 
    br[x + 1][y] ^= 1; 
    br[x][y - 1] ^= 1; 
    br[x][y + 1] ^= 1; 
}

bool Solve(int & sm)
{
    memcpy(br, ar, sizeof(ar));
    for(int i = 1; i <= m; i ++)        //反转第一行
        if(op[1][i]) turn(1, i);
    for(int i = 2; i <= n; i ++)        //反转其它行
        for(int j = 1; j <= m; j ++)
        {
            if(br[i - 1][j]) 
            {
                turn(i, j);
                op[i][j] = 1;
                sm ++;
            }
        }
    for(int i = 1; i <= m; i ++)
        if(br[n][i]) return false;
    return true;
}

int main()
{
    /* fre(); */
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= m; j ++)
            scanf("%d", &ar[i][j]);

    int sum = INF;
    for(int i = 0; i < (1 << m + 1); i ++)          //二进制枚举第一行的每个位置的是否反转的情况2^15 
    {
        memset(op, 0, sizeof(op));
        int sm = 0;                                 //总共的反转次数
        for(int j = 1, t = i; j <= m; j ++)         //第一行反转情况进行赋值
        {
            op[1][j] = (t & 1); 
            sm += op[1][j];
            t >>= 1;
        }

        if(Solve(sm) && sm < sum)
        {
            sum = sm;
            memcpy(ans, op, sizeof(op));
        }
    }

    if(sum == INF)
        printf("IMPOSSIBLE\n"), exit(0);

    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= m; j ++)
            printf("%d ", ans[i][j]);
        printf("\n");
    }

    return 0;
}


E - Find The Multiple POJ - 1426

思路

  1. 这题怎么说呢,对于当前题目的给定的数据范围,我们可以知道 我所要凑出来的0、1组成的数字是不会超过 long long 数据范围的,所以可以直接用dfs暴力模拟过程求解,
  2. 但是当数据范围的 在扩大的时候,,,这时候 就要对dfs进行优化的了(用 同余定理 什么的)

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
using namespace std;

const int mxn = 20;
int n, fg;

void dfs(int cur, ll num)          //cur 表示是十进制是几位、num表示当前 枚举的数
{
    if(cur == 19 || fg)
        return;
    if(num % n == 0)
    {
        printf("%lld\n", num);
        fg = 1;
        return;
    }
    
    dfs(cur + 1, num * 10);
    dfs(cur + 1, num * 10 + 1);
}

int main()
{
    /* fre(); */
    while(scanf("%d", &n) && n)
    {
        fg = 0;
        dfs(0, 1);
    }

    return 0;
}


F - Prime Path POJ - 3126

思路

  1. 这一题的思路是 对于所给的起点和终点的两个四位数质数:x和y,我可以用bfs 去暴力扩展搜索所有的 四位数质数 从x出发最先扩展到y的耗费的操作的次数的就是我们你的ans

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
using namespace std;

const int mxn = 1e5;
struct Node
{
    int x, t;
};
int s, e;
int mk[mxn];
int pr[mxn];

void prime()
{
    fill(pr + 1, pr + mxn, 1);
    for(int i = 2; i * i < mxn; i ++)
    {
        if(pr[i])
            for(int j = i * i; j < mxn; j += i)
                pr[j] = 0;
    }
}


void bfs()
{
    memset(mk, 0, sizeof(mk));
    queue<Node> q;
    q.push((Node){ s, 0 });
    while(! q.empty())
    {
        Node now = q.front(); q.pop();
        if(now.x == e)
        {
            printf("%d\n", now.t);
            return;
        }
        //个位
        for(int i = 1; i < 10; i += 2)
        {
            int t = now.x / 10 * 10 + i;
            if(! mk[t] && pr[t])
                q.push((Node){ t, now.t + 1 }), mk[t] = 1;
        }
        //十位
        for(int i = 0; i < 10; i ++)
        {
            int t = now.x % 10 + now.x / 100 * 100 + i * 10;
            if(! mk[t] && pr[t])
                q.push((Node){ t, now.t + 1 }), mk[t] = 1;
        }
        //百位
        for(int i = 0; i < 10; i ++)
        {
            int t = now.x % 100 + now.x / 1000 * 1000  + i * 100;
            /* cout << t <<endl; */
            if(! mk[t] && pr[t])
                q.push((Node){ t, now.t + 1 }), mk[t] = 1;
        }
        //千位
        for(int i = 1; i < 10; i ++)
        {
            int t = now.x % 1000 + i * 1000;
            if(! mk[t] && pr[t])
                q.push((Node){ t, now.t + 1 }), mk[t] = 1;
        }
    }
}


int main()
{
    /* fre(); */
    int T;
    scanf("%d", &T);

    prime();
    while(T --)
    {
        scanf("%d %d", &s, &e);
        bfs();
    }

    return 0;
}



G - Shuffle’m Up POJ - 3087

思路

  1. 这题没啥说的,就是在暴力dfs 的时候,我们要 暴力 做标记, 减少不必要的 搜索过程

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<map>
#include<string>
#include<cstdio>
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
using namespace std;

const int mxn = 1e5;
int n;
string a, b, c;
map<string, int> mp;

int dfs(string s, int k) 
{
    if(s == c)
        return k;

    if(! mp[s])
    {
        mp[s] = 1;

        string t;
        for(int i = 0; i < n; i ++)
        {
            t += s[n + i];
            t += s[i];
        }

        int val = dfs(t, k + 1);
        if(val != -1)
            return val;
    }
    return -1;
}


int main()
{
    ios;
    /* fre(); */
    int T, Case = 1;
    cin >> T;
    while(T --)
    {
        mp.clear();
        cin >> n;
        cin >> a >> b >> c;
        string t;
        for(int i = 0; i < n; i ++)
        {
            t += b[i];
            t += a[i];
        }
        cout << Case ++ << " " << dfs(t, 1) << endl;
    }


    return 0;
}


H - Pots POJ - 3414

思路

  1. 这题用 bfs进行搜索答案,
  2. 用并查集知识输出答案, 对于每个位置/状态,我们存储这个位置/状态的 父节点 位置/状态,这一题我们需要注意,这一题并没有明显的位置的或者状态,那么我们可以自己来创造 这个 位置/状态,
    1. 对于题目给的3中操作,由于是2个物品,所有我们在bfs中可以进行6中操作,我们给这六种操作分别 编上编号为1~6,我们 用这是第几次(设为t次)对两个物品操作设为,那么我们可以用 t * 10 + 该操作编号 = 位置/状态x,这样对于不同的状态就有不同的 标识编号了,这样就能 桶这个 表示 作为并查集的 f [ ] f[] f[]的下标了
  3. 最后用并查集 递归输出答案所需的格式

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<map>
#include<string>
#include<cstdio>
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
using namespace std;

const int mxn = 1e5;
int n;
string a, b, c;
map<string, int> mp;

int dfs(string s, int k) 
{
    if(s == c)
        return k;

    if(! mp[s])
    {
        mp[s] = 1;

        string t;
        for(int i = 0; i < n; i ++)
        {
            t += s[n + i];
            t += s[i];
        }

        int val = dfs(t, k + 1);
        if(val != -1)
            return val;
    }
    return -1;
}


int main()
{
    ios;
    /* fre(); */
    int T, Case = 1;
    cin >> T;
    while(T --)
    {
        mp.clear();
        cin >> n;
        cin >> a >> b >> c;
        string t;
        for(int i = 0; i < n; i ++)
        {
            t += b[i];
            t += a[i];
        }
        cout << Case ++ << " " << dfs(t, 1) << endl;
    }


    return 0;
}


I - Fire Game FZU - 2150

思路

  1. 这一题 明显的bfs,但是在bfs 的过程中,有个难题就是 『题目要求:我们要人为先选两处草所在的方格把他们变成 🔥区域方格』,在选变🔥方格的时候出先了问题:怎么选 才能最优(🔥烧光所有的草需要的时间最少)?
  2. 对与这一难题,由于题目数据范围,真的很小,所以 暴力枚举 所有可能的选择位置,对于每一种 位置情况我们 都跑一遍 bfs,之后对所有情况维护一下 最优解

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <cstring>
using namespace std;
 
typedef long long ll;
typedef struct node {
    int x, y, step;
} node;
const int maxn = 1e5 + 10;
const int INF = (1 << 30);
int t, n, m, ans;
int vis[15][15], cnt[15][15];
char mp[15][15];
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1} };
bool check(int x, int y) {
    if(x < 0 || x > n - 1 || y < 0 || y > m - 1 || vis[x][y] || mp[x][y] == '.') {
        return 0;
    }
    return 1;
}
bool allright() {
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            if(!vis[i][j] && mp[i][j] == '#') {
                return 0;
            }
        }
    }
    return 1;
}
int BFS(node a, node b) {
    queue<node> P;
    memset(vis, 0, sizeof(vis));
    vis[a.x][a.y] = vis[b.x][b.y] = 1;
    a.step = b.step = 0;
    P.push(a);
    P.push(b);
    int steps = 0;
    while(!P.empty()) {
        node p = P.front();
        steps = p.step;
        P.pop();
        for(int i = 0; i < 4; i++) {
            node nn;
            nn.x = p.x + dir[i][0];
            nn.y = p.y + dir[i][1];
            if(check(nn.x, nn.y)) {
                nn.step = p.step + 1;
                P.push(nn);
                vis[nn.x][nn.y] = 1;
            }
        }
    }
    return steps;
}
int main() {
    ios::sync_with_stdio(false);
    cin >> t;
    int icase = 1;
    while(t--) {
        vector<node> Q;
        cin >> n >> m;
        for(int i = 0; i < n; i++) {
            cin >> mp[i];
            for(int j = 0; j < m; j++) {
                if(mp[i][j] == '#') {
                    node p;
                    p.x = i;
                    p.y = j;
                    p.step = 0;
                    Q.push_back(p);
                }
            }
        }
        int ans = INF;
        for(int i = 0; i < Q.size(); i++) {
            for(int j = i; j < Q.size(); j++) {
                int x = BFS(Q[i], Q[j]);
                if(allright()) {
                    ans = min(ans, x);
                }
            }
        }
        if(ans != INF) {
            cout << "Case " << icase++ << ": " << ans << endl;
        } else {
            cout << "Case " << icase++ << ": " << -1 << endl;
        }
    }
    return 0;
}


J - Fire! UVA - 11624

思路

  1. 这题的思路很简单,既然 🔥 会向四周蔓延,那么那么我们先对🔥用一遍bfs统计出,🔥到打每一个位置所需要的时间,
  2. 既然人会跑,那么我们也对人用一遍bfs,只不过人在bfs 的过程中 能够从一个位置走到相邻四周的某个位置(i,j),我们就要 比较 人到打(i,j)这个位置所用的时间 和 🔥到打这个位置的所用的时间(这里 🔥到达的时间是 我们对🔥用bfs 的时候统计出的数据),之后人到达(i,j)位置的时间 < 🔥到达的,才可以 人才可以到达这个位置,
  3. 因此这样对人bfs一遍之后,我找出所有能到的 出口 的路线中耗时最短的那个就可以了

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>

using namespace std;

const int Len = 1005;
char map[Len][Len];
int mov[4][2] = { {1,0},{0,1},{-1,0},{0,-1}};
int tim[Len][Len];
int mark[Len][Len];
vector<pair<int , int > > pir;
int m,n;
int x,y;
struct Node
{
    int x,y,t;
}st,ed;
queue<Node> q;

//火专用
void bfs_fire()
{
    //初始化
    for(int i = 0; i < m; i ++)
        for(int j = 0; j < n; j ++)
            tim[i][j] = 1e9;
    while(pir.size() > 0)
    {
        st.x = pir.back().first;
        st.y = pir.back().second;
        st.t = 0;
        tim[st.x][st.y] = 0;
        q.push(st);
        pir.pop_back();
    }
    while(! q.empty())
    {
        st = q.front();
        q.pop();

        for(int i = 0; i < 4; i ++)
        {
            ed.x = st.x + mov[i][0];
            ed.y = st.y + mov[i][1];
            ed.t = st.t + 1;
            if(ed.x >= 0 && ed.y >= 0 && ed.x < m && ed.y < n && map[ed.x][ed.y] != '#' && tim[ed.x][ed.y] > ed.t)
            {
                tim[ed.x][ed.y] = ed.t;
                q.push(ed);
            }
        }
    }
}

int min_time;
//人专用
bool bfs_man()
{
    bool flag = 0;
    //各种初始化、赋值、做标记、压队列
    min_time = 1e9;
    memset(mark , 0 , sizeof(mark));
    st.x = x;
    st.y = y;
    st.t = 0;
    mark[st.x][st.y] = 1;
    q.push(st);
    while(! q.empty())
    {
        st = q.front();
        q.pop();
        if(st.x == 0 || st.y == 0 || st.x == m - 1 || st.y == n - 1)
        {
            flag = 1;
            min_time = min(min_time , st.t);
            continue;
        }

        for(int i = 0; i < 4; i ++)
        {
            ed.x = st.x + mov[i][0];
            ed.y = st.y + mov[i][1];
            ed.t = st.t + 1;
            if(ed.x >= 0 && ed.y >= 0 && ed.x < m && ed.y < n && map[ed.x][ed.y] != '#' && mark[ed.x][ed.y] == 0 && ed.t < tim[ed.x][ed.y])
            {
                mark[ed.x][ed.y] = 1;
                q.push(ed);
            }
        }
    }
    return flag;
}

int main()
{
    //freopen("test.txt","r",stdin);
    int t;
    scanf("%d", &t);
    while(t --)
    {
        scanf("%d %d ", &m, &n);
        pair<int , int> pirr;
        for(int i = 0; i < m; i ++)
        {
            for(int j = 0; j < n; j ++)
            {
                scanf("%c", &map[i][j]);
                if(map[i][j] == 'J')
                {
                    x = i,y = j;
                }
                else if(map[i][j] == 'F')
                {
                    pirr.first = i;
                    pirr.second = j;
                    pir.push_back(pirr);
                }
            }
            getchar();
        }
        bfs_fire();
//        for(int i = 0; i < m; i ++)
//        {
//            for(int j = 0; j < n; j ++)
//            {
//                printf("%d ",tim[i][j]);
//            }
//            printf("\n");
//        }
        if(bfs_man())
        {
            printf("%d\n",min_time + 1);
        }
        else
            printf("IMPOSSIBLE\n");


    }

    return 0;
}


K - 迷宫问题 POJ - 3984

思路

  1. 水题。。。。

代码

//深搜版
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
const int Len = 5;
int map[Len][Len];
int mark[Len][Len];
int mov[4][2] = { {1,0},{0,1},{-1,0},{0,-1} };
int s_x = 0,s_y = 0,e_x = 4,e_y = 4;
struct Node
{
    int x,y;
}tem,s,e,node[Len][Len];
stack<Node> st;
queue<Node> q;

bool is_good(int x,int y)
{
    if(x >= 0 && y >= 0 && x < 5 && y < 5 && ! mark[x][y] && map[x][y] != 1)
        return true;
    return false;
}

int flag = 0;
void dfs(int x,int y)
{
    if(x == e_x && y == e_y)
    {
        flag = 1;
        //printf("(%d,%d)\n",x,y);
        tem.x = x,tem.y = y;
        st.push(tem);
        return;
    }
    for(int i = 0; i < 4; i ++)
    {
        int xx = x + mov[i][0];
        int yy = y + mov[i][1];
        if(is_good(xx , yy))
        {
            mark[xx][yy] = 1;
            dfs(xx , yy);
            if(flag ==  1)
            {
                //printf("(%d,%d)\n",x,y);
                tem.x = x,tem.y = y;
                st.push(tem);
                return;
            }
            mark[xx][yy] = 0;
        }
    }
}

void print(int x,int y)
{
    if(node[x][y].x == x && node[x][y].y == y)
    {
        printf("(%d, %d)\n",x,y);
        return;
    }
    print(node[x][y].x , node[x][y].y);
        printf("(%d, %d)\n",x,y);
}

void bfs()
{
    //初始化、赋值、做标记、压队列
    s.x = s_x;
    s.y = s_y;
    node[s.x][s.y].x = s.x;
    node[s.x][s.y].y = s.y;
    mark[s.x][s.y] = 1;
    q.push(s);
    while(! q.empty())
    {
        s = q.front();
        q.pop();

        if(s.x == e_x && s.y == e_y)
        {
            print(s.x , s.y);
            return;
        }
        for(int i = 0; i < 4; i ++)
        {
            e.x = s.x + mov[i][0];
            e.y = s.y + mov[i][1];
            if(is_good(e.x , e.y))
            {
                node[e.x][e.y].x = s.x;
                node[e.x][e.y].y = s.y;
                mark[e.x][e.y] = 1;
                q.push(e);
            }
        }
    }
}

int main()
{
    //freopen("T.txt","r",stdin);

    for(int i = 0; i < Len; i ++)
        for(int j = 0; j < Len; j ++)
            scanf("%d", &map[i][j]);
    bfs();
    return 0;
}

L - Oil Deposits HDU - 1241

思路

  1. 水题

代码

#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

typedef struct node {
    int x,y;
} ty;

char a[102][102];
int via[102][102];
int n,m;
int ans;
ty t,d;

void bfs( int x, int y )
{
    int next[8][2] = {
        {1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{1,-1},{-1,1}
    };
    ans ++;
    queue <ty> Q;
    t.x = x;
    t.y = y;
    Q.push(t);
    via[t.x][t.y] = 0;

    while ( !Q.empty() ) {
        t = Q.front();
        Q.pop();

        for ( int i=0; i<8; i++ ) {
            d.x = t.x + next[i][0];
            d.y = t.y + next[i][1];

            if ( d.x<0 || d.y<0 || d.x>=n || d.y>=m )  continue;
            
            if ( a[d.x][d.y]=='@' && via[d.x][d.y]==0 ) {
                via[d.x][d.y] = 1;
                Q.push(d);
            }
        }
    }
}

int main()
{
    int i,j;
    while ( cin>>n>>m && n!=0 && m!=0 ) {
        for ( i=0; i<n; i++ ) {
            for ( j=0; j<m; j++ ) {
                cin >> a[i][j];
            }
        }

        ans = 0;
        memset(via,0,sizeof(via));
        for ( i=0; i<n; i++ ) { // 便利所有田
            for ( j=0; j<m; j++ ) {
                if ( a[i][j]=='@' && via[i][j]==0 ) {
                    bfs(i,j);
                }
            }
        }
        cout << ans << endl;

    }

    return 0;
}


M - 非常可乐 HDU - 1495

思路

  1. 用bfs,开三维数组暴力标记 已经 扩展到的状态,
  2. 对于每次操作:对于每个杯子,我们都可把 它 里面的可乐倒入 其它的杯子

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<map>
#include<string>
#include<cstdio>
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
using namespace std;

const int mxn = 105;
int mk[mxn][mxn][mxn];
int x, y, z;
struct Node
{
    int a, b, c, t;
};
bool check(Node s)
{
    if(s.a != 0 && s.a != x / 2) return false;
    if(s.b != 0 && s.b != x / 2) return false;
    if(s.c != 0 && s.c != x / 2) return false;
    return true;
}

void bfs()
{
    memset(mk, 0, sizeof(mk));
    mk[x][0][0] = 1;
    queue<Node> q;
    q.push((Node){ x, 0, 0, 0 });

    while(! q.empty())
    {
        Node s = q.front(); q.pop();
        if(check(s))
        {
            printf("%d\n", s.t);
            return;
        }

        if(s.a)
        {
            if(s.b < y)
            {
                int v = min(s.a, y - s.b);
                if(! mk[s.a - v][s.b + v][s.c])
                {
                    mk[s.a - v][s.b + v][s.c] = 1;
                    q.push((Node){ s.a - v, s.b + v, s.c, s.t + 1 });
                }
            }
            if(s.c < z)
            {
                int v = min(s.a, z - s.c);
                if(! mk[s.a - v][s.b][s.c + v])
                {
                    mk[s.a - v][s.b][s.c + v] = 1;
                    q.push((Node){ s.a - v, s.b, s.c + v, s.t + 1 });

                }
            }
        }

        if(s.b)
        {
            if(s.a < x)
            {
                int v = min(s.b, x - s.a);
                if(! mk[s.a + v][s.b - v][s.c])
                {
                    mk[s.a + v][s.b - v][s.c] = 1;
                    q.push((Node){ s.a + v, s.b - v, s.c, s.t + 1 });

                }

            }
            if(s.c < z)
            {
                int v = min(s.b, z - s.c);
                if(! mk[s.a][s.b - v][s.c + v])
                {
                    mk[s.a][s.b - v][s.c + v] = 1;
                    q.push((Node){ s.a, s.b - v, s.c + v, s.t + 1 });
                }
            }
        }

        if(s.c)
        {
            if(s.a < x)
            {
                int v = min(s.c, x - s.a);
                if(! mk[s.a + v][s.b][s.c - v])
                {
                    mk[s.a + v][s.b][s.c - v] = 1;
                    q.push((Node){ s.a + v, s.b, s.c - v, s.t + 1 });

                }
            }
            if(s.b < y)
            {
                int v = min(s.c, y - s.b);
                if(! mk[s.a][s.b + v][s.c - v]) 
                {
                    mk[s.a][s.b + v][s.c - v] = 1;
                    q.push((Node){ s.a, s.b + v, s.c - v, s.t + 1 });
                }
            }
        }
    }

    printf("NO\n");
}


int main()
{
    /* fre(); */
    while(scanf("%d %d %d", &x, &y, &z) && x)
    {
        if(x % 2)
            printf("NO\n");
        else
            bfs();
    }

    return 0;
}

N - Find a way HDU - 2612

思路

  1. 对两个人分别 跑一下bfs,之后统计到达 相同地点的时间和,找出最小时间和

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<map>
#include<string>
#include<cstdio>
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod (ll)(1e9 + 7)
using namespace std;

const int mxn = 205;
int n, m;
char mz[mxn][mxn];
int mov[4][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
int mk[mxn][mxn];

struct Node
{
    int x, y, t;
}s1, s2;
vector<Node> e;
int t1[mxn][mxn], t2[mxn][mxn];

bool check(int x, int y)
{
    if(x >= 1 && y >= 1 && x <= n && y <= m && mz[x][y] != '#' && ! mk[x][y])
        return true;
    return false;
}

void bfs(Node s, int t[mxn][mxn])
{
    memset(mk, 0, sizeof(mk));
    mk[s.x][s.y] = 1;
    queue<Node> q;
    q.push(s);
    while(! q.empty())
    {
        s = q.front(); q.pop();
        if(mz[s.x][s.y] == '@' && ! t[s.x][s.y])
            t[s.x][s.y] = s.t;

        for(int i = 0; i < 4; i ++)
        {
            Node now = (Node){ s.x + mov[i][0], s.y + mov[i][1], s.t + 11 };
            if(! check(now.x, now.y)) continue;
            q.push(now);
            mk[now.x][now.y] = 1;
        }
    }
}

int main()
{
    /* fre(); */
    while(~ scanf("%d %d", &n, &m))
    {
        memset(t1, 0, sizeof(t1));
        memset(t2, 0, sizeof(t2));
        e.clear();
        for(int i = 1; i <= n; i ++)
        {
            scanf("%s", mz[i] + 1);
            for(int j = 1; j <= m; j ++)
            {
                if(mz[i][j] == 'Y')
                    s1 = (Node){ i, j, 0 };
                if(mz[i][j] == 'M')
                    s2 = (Node){ i, j, 0 };
                if(mz[i][j] == '@')
                    e.push_back((Node){ i, j });
            }
        }
        bfs(s1, t1);
        bfs(s2, t2);

        int ans = INF;
        for(auto p : e)
            if(t1[p.x][p.y] && t2[p.x][p.y])
                ans = min(ans, t1[p.x][p.y] + t2[p.x][p.y]);
        printf("%d\n", ans);
    }


    return 0;
}


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
4S店客户管理小程序-毕业设计,基于微信小程序+SSM+MySql开发,源码+数据库+论文答辩+毕业论文+视频演示 社会的发展和科学技术的进步,互联网技术越来越受欢迎。手机也逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用。手机具有便利性,速度快,效率高,成本低等优点。 因此,构建符合自己要求的操作系统是非常有意义的。 本文从管理员、用户的功能要求出发,4S店客户管理系统中的功能模块主要是实现管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理,用户客户端:首页、车展、新闻头条、我的。门店客户端:首页、车展、新闻头条、我的经过认真细致的研究,精心准备和规划,最后测试成功,系统可以正常使用。分析功能调整与4S店客户管理系统实现的实际需求相结合,讨论了微信开发者技术与后台结合java语言和MySQL数据库开发4S店客户管理系统的使用。 关键字:4S店客户管理系统小程序 微信开发者 Java技术 MySQL数据库 软件的功能: 1、开发实现4S店客户管理系统的整个系统程序; 2、管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理等。 3、用户客户端:首页、车展、新闻头条、我的 4、门店客户端:首页、车展、新闻头条、我的等相应操作; 5、基础数据管理:实现系统基本信息的添加、修改及删除等操作,并且根据需求进行交流信息的查看及回复相应操作。
现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本微信小程序医院挂号预约系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此微信小程序医院挂号预约系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。微信小程序医院挂号预约系统有管理员,用户两个角色。管理员功能有个人中心,用户管理,医生信息管理,医院信息管理,科室信息管理,预约信息管理,预约取消管理,留言板,系统管理。微信小程序用户可以注册登录,查看医院信息,查看医生信息,查看公告资讯,在科室信息里面进行预约,也可以取消预约。微信小程序医院挂号预约系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值