zoukankan      html  css  js  c++  java
  • POJ 简单搜索

    简单搜索

    深度优先搜索

    poj2488,poj3083,poj3009,poj1321

    广度优先搜索

    poj2251,poj1426,poj3126,poj3087.poj3414

    poj 1606

    简单搜索技巧和剪枝

    poj2531,poj1416,poj2676,poj1129

     poj 2488

    好恶心的题。。。应该用深搜的,我用的bfs,wa掉,改成dfs,还是wa。。。注意向八个方向扩展的顺序,保证输出结果按字典序排列。

    int dir[8][2] = {{-2, -1},{-2, 1},{-1, -2},{-1, 2},{1, -2},{1, 2},{2, -1},{2, 1}};

    贡献无数wa,T_T

      

     poj 3083

    求左优先和右优先的时候用dfs,注意顺序。

    int Left[4][2] = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
    int Right[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    View Code
      1 #include <iostream>
    2 #include <cstring>
    3 #include <cstdio>
    4 #include <queue>
    5
    6 using namespace std;
    7
    8 const int N = 100;
    9
    10 struct node {
    11 int x;
    12 int y;
    13 int s;
    14 } q[100000];
    15
    16 char mp[N][N];
    17 int vis[N][N];
    18 int w, h, dir;
    19 int si, sj, ei, ej;
    20
    21 int Left[4][2] = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
    22 int Right[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
    23
    24 bool inMap(int x, int y) {
    25 if(x < 0 || x >= h || y < 0 || y >= w) return false;
    26 return true;
    27 }
    28
    29 int dfs_l(int x, int y, int s) {
    30 if(x == ei && y == ej) {
    31 return s + 1;
    32 }
    33 if(!inMap(x, y) || mp[x][y] == '#') return 0;
    34 dir = (dir + 3) % 4;
    35 int tmp;
    36 while(1) {
    37 tmp = dfs_l(x + Left[dir][0], y + Left[dir][1], s + 1);
    38 if(tmp > 0) break;
    39 dir = (dir + 1) % 4;
    40 }
    41 }
    42
    43 int dfs_r(int x, int y, int s) {
    44 if(x == ei && y == ej) {
    45 return s + 1;
    46 }
    47 if(!inMap(x, y) || mp[x][y] == '#') return 0;
    48 dir = (dir + 3) % 4;
    49 int tmp;
    50 while(1) {
    51 tmp = dfs_r(x + Right[dir][0], y + Right[dir][1], s + 1);
    52 if(tmp > 0) break;
    53 dir = (dir + 1) % 4;
    54 }
    55 }
    56
    57 int bfs() {
    58 int f = 0, r = 0, i;
    59 node u, v;
    60 q[r].x = si; q[r].y = sj; q[r++].s = 0;
    61 vis[si][sj] = true;
    62
    63 while(f < r) {
    64 u = q[f++];
    65 if(u.x == ei && u.y == ej) return u.s + 1;
    66 for(i = 0; i < 4; ++i) {
    67 v.x = u.x + Left[i][0];
    68 v.y = u.y + Left[i][1];
    69 v.s = u.s + 1;
    70 if(inMap(v.x, v.y) && !vis[v.x][v.y] && mp[v.x][v.y] != '#') {
    71 vis[v.x][v.y] = true;
    72 q[r++] = v;
    73 }
    74 }
    75 }
    76 return 0;
    77 }
    78
    79 int main() {
    80 //freopen("data.in", "r", stdin);
    81
    82 int t, i, j, l, r;
    83 scanf("%d", &t);
    84 while(t--) {
    85 scanf("%d%d", &w, &h);
    86
    87 for(i = 0; i < h; ++i) {
    88 scanf("%s", mp[i]);
    89 for(j = 0; j < w; ++j) {
    90 if(mp[i][j] == 'S') {
    91 si = i; sj = j;
    92 }
    93 if(mp[i][j] == 'E') {
    94 ei = i; ej = j;
    95 }
    96 }
    97 }
    98 memset(vis, 0, sizeof(vis));
    99 dir = 0;
    100 l = dfs_l(si, sj, 0);
    101 dir = 0;
    102 r = dfs_r(si, sj, 0);
    103 printf("%d %d %d\n", l, r, bfs());
    104 }
    105 return 0;
    106 }


     poj 1321

      f(i, k)表示一颗棋子至少应该放在第i行,并且当前共有k个棋子要放。

    0 <= i <= n - k

    f(i, k) = f(i + 1, k)(这一行不放,还有剩k个要放) + sum(f(i + 1, k - 1))(这一行放,枚举列数累加下一行可放的情况数)

    View Code
    1         res += dfs(r + 1, k);
    2 for(i = 0; i < n; ++i) {
    3 if(mp[r][i] == '#' && !cm[i] && !rm[r]) {
    4 cm[i] = true; rm[r] = true;
    5 res += dfs(r + 1, k - 1);
    6 cm[i] = false; rm[r] = false;
    7 }
    8 }


    poj 2251

    三维的搜索题,直接写bfs。跟HDU_1253 胜利大逃亡(BFS)

    一样的题。。。话说,这两天来终于1A一次了. =_=///

    渣代码:

    View Code
     1 #include <iostream>
    2 #include <cstring>
    3 #include <cstdio>
    4 #include <cstdlib>
    5
    6 using namespace std;
    7
    8 const int N = 33;
    9
    10 class node {
    11 public:
    12 int y, x;
    13 int l, t;
    14
    15 bool indung();
    16 bool operator == (const node & c) {
    17 return (l == c.l && x == c.x && y == c.y);
    18 }
    19 } q[100000];
    20
    21 node s, e;
    22 int le, rl, cw;
    23 char mp[N][N][N];
    24 bool vis[N][N][N];
    25
    26 int dir[6][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0},
    27 {0, -1, 0}, {0, 0, -1}, {0, 0, 1}};
    28
    29
    30 bool node::indung() {
    31 if(l >= 0 && l < le) {
    32 if(x >= 0 && x < rl) {
    33 if(y >= 0 && y < cw) return true;
    34 }
    35 }
    36 return false;
    37 }
    38
    39 int bfs() {
    40 int f = 0, r = 0, i;
    41 q[r++] = s;
    42 memset(vis, 0, sizeof(vis));
    43 vis[s.l][s.x][s.y] = true;
    44 node u, v;
    45 while(f < r) {
    46 u = q[f++];
    47 if(u == e) return u.t;
    48
    49 for(i = 0; i < 6; ++i) {
    50 v.l = u.l + dir[i][0];
    51 v.x = u.x + dir[i][1];
    52 v.y = u.y + dir[i][2];
    53 v.t = u.t + 1;
    54 if(v.indung() && !vis[v.l][v.x][v.y] && mp[v.l][v.x][v.y] != '#') {
    55 vis[v.l][v.x][v.y] = true;
    56 q[r++] = v;
    57 }
    58 }
    59 }
    60 return -1;
    61 }
    62
    63 int main() {
    64 //freopen("data.in", "r", stdin);
    65
    66 int i, j, k, ans;
    67 while(~scanf("%d%d%d", &le, &rl, &cw)) {
    68 if(!le && !rl && !cw) break;
    69
    70 for(i = 0; i < le; ++i) {
    71 for(j = 0; j < rl; ++j) {
    72 scanf("%s", mp[i][j]);
    73 for(k = 0; k < cw; ++k) {
    74 if(mp[i][j][k] == 'S') {
    75 s.l = i; s.x = j; s.y = k; s.t = 0;
    76 }
    77 if(mp[i][j][k] == 'E') {
    78 e.l = i; e.x = j; e.y = k; e.t = 0;
    79 }
    80 }
    81 }
    82 }
    83 ans = bfs();
    84 if(ans < 0) puts("Trapped!");
    85 else {
    86 printf("Escaped in %d minute(s).\n", ans);
    87 }
    88 }
    89 return 0;
    90 }



    poj 1426

    题意是给一个n,求一个十进制数m。满足m仅由0, 1组成。还好这个是个Special Judge,思路是从1开始,每次左移一位(后边补0)判断移位后和移位+1后能否整除n。记录每种状态bfs

    ps: 没写头文件<string>,我电脑的编译器居然很智能的没判出来,和本人犯这种白痴级问题的脑袋形成鲜明的对比!!!

     poj 3126

    数据很水,本菜的暴力bfs没加任何剪枝,居然0ms过了。刚开始素数表打错了。wa了一次,检讨!

    代码有点shi。。。

    View Code
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <string>

    using namespace std;

    const int N = 10010;

    struct node {
    int x;
    int t;
    } q[100000];

    int prim[N];
    int base[4] = {1, 10, 100, 1000};
    int s, e;
    bool vis[N];

    void init() {
    int i, j;
    memset(prim, true, sizeof(prim));
    for(i = 2; i < 10000; ++i) {
    for(j = 2; j < 10000; ++j) {
    if(i *j > 10000) break;
    prim[i*j] = false;
    }
    }
    }

    int bfs() {
    int f = 0, r = 0, i, tmp;
    node u, v;
    u.x = s; u.t = 0;
    q[r++] = u;
    memset(vis, false, sizeof(vis));
    vis[s] = true;
    int x1, x2, x3, x4;

    while(f < r) {
    u = q[f++];
    if(u.x == e) return u.t;
    x1 = u.x % 10;
    x2 = u.x % 100 - x1;
    x3 = u.x % 1000 - x2 - x1;
    x4 = u.x - x3 - x2 - x1;
    //printf("%d %d %d %d\n", x1, x2, x3, x4);
    //1
    tmp = x4 + x3 + x2;
    for(i = 1; i < 10; ++i) {
    v.x = tmp + (i);
    if(v.x == u.x) continue;
    if(prim[v.x] && !vis[v.x]) {
    vis[v.x] = true;
    v.t = u.t + 1;//printf("%d %d\n", v.x, v.t);
    q[r++] = v;
    }
    }
    //10
    tmp = x4 + x3 + x1;
    for(i = 0; i < 10; ++i) {
    v.x = tmp + (i*10);
    if(v.x == u.x) continue;
    if(prim[v.x] && !vis[v.x]) {
    vis[v.x] = true;
    v.t = u.t + 1;//printf("%d %d\n", v.x, v.t);
    q[r++] = v;
    }
    }
    //100
    tmp = x4 + x2 + x1;
    for(i = 0; i < 10; ++i) {
    v.x = tmp + (i*100);
    if(v.x == u.x) continue;
    if(prim[v.x] && !vis[v.x]) {
    vis[v.x] = true;
    v.t = u.t + 1;//printf("%d %d\n", v.x, v.t);
    q[r++] = v;
    }
    }
    //1000
    tmp = x3 + x2 + x1;
    for(i = 1; i < 10; ++i) {
    v.x = tmp + (i*1000);
    if(v.x == u.x) continue;
    if(prim[v.x] && !vis[v.x]) {
    vis[v.x] = true;
    v.t = u.t + 1;//printf("%d %d\n", v.x, v.t);
    q[r++] = v;
    }
    }
    }
    return -1;
    }

    int main() {
    //freopen("data.in", "r", stdin);
    //freopen("data.out", "w", stdout);
    int t, ans;
    scanf("%d", &t);
    init();
    while(t--) {
    scanf("%d%d", &s, &e);
    ans = bfs();
    cout << ans << endl;
    }
    return 0;
    }


    poj 3414

    bfs,回溯输出路径。 (poj 1606相同)

    View Code
      1 #include <iostream>
    2 #include <cstring>
    3 #include <cstdio>
    4 #include <cmath>
    5
    6 using namespace std;
    7
    8 const int N = 110;
    9
    10 struct node {
    11 int potA;
    12 int potB;
    13 int pre;
    14 int stp;
    15 int flg;
    16 } q[100000];
    17
    18 bool vis[N][N];
    19 int A, B, C;
    20
    21 void dfs(int p) {
    22 if(q[p].pre == -1) return ;
    23 dfs(q[p].pre);
    24
    25 switch(q[p].flg) {
    26 case 0: puts("FILL(1)"); break;
    27 case 1: puts("DROP(1)"); break;
    28 case 2: puts("POUR(2,1)"); break;
    29 case 3: puts("FILL(2)"); break;
    30 case 4: puts("DROP(2)"); break;
    31 case 5: puts("POUR(1,2)"); break;
    32 }
    33
    34 }
    35
    36 void potA(node& v, node u, int& r) {
    37 //fill
    38 v.potA = A; v.potB = u.potB; v.flg = 0;
    39 if(!vis[v.potA][v.potB]) {
    40 vis[v.potA][v.potB] = true;
    41 q[r++] = v;
    42 }
    43 //drop
    44 v.potA = 0; v.potB = u.potB; v.flg = 1;
    45 if(!vis[v.potA][v.potB]) {
    46 vis[v.potA][v.potB] = true;
    47 q[r++] = v;
    48 }
    49 //pour
    50 v.flg = 2;
    51 if(u.potB <= A - u.potA) {
    52 v.potB = 0;
    53 v.potA = u.potA + u.potB;
    54 } else {
    55 v.potB = u.potB - (A - u.potA);
    56 v.potA = A;
    57 }
    58 if(!vis[v.potA][v.potB]) {
    59 vis[v.potA][v.potB] = true;
    60 q[r++] = v;
    61 }
    62 }
    63
    64 void potB(node& v, node u, int& r) {
    65 //fill
    66 v.potB = B; v.potA = u.potA; v.flg = 3;
    67 if(!vis[v.potA][v.potB]) {
    68 vis[v.potA][v.potB] = true;
    69 q[r++] = v;
    70 }
    71 //drop
    72 v.potB = 0; v.potA = u.potA; v.flg = 4;
    73 if(!vis[v.potA][v.potB]) {
    74 vis[v.potA][v.potB] = true;
    75 q[r++] = v;
    76 }
    77 //pour
    78 v.flg = 5;
    79 if(u.potA <= B - u.potB) {
    80 v.potA = 0;
    81 v.potB = u.potB + u.potA;
    82 } else {
    83 v.potA = u.potA - (B - u.potB);
    84 v.potB = B;
    85 }
    86 if(!vis[v.potA][v.potB]) {
    87 vis[v.potA][v.potB] = true;
    88 q[r++] = v;
    89 }
    90 }
    91
    92 void bfs() {
    93 int f = 0, r = 0;
    94 node u, v;
    95 u.potA = u.potB = 0;
    96 u.pre = -1; u.stp = 0;
    97 q[r++] = u;
    98 memset(vis, 0, sizeof(vis));
    99 vis[0][0] = true;
    100
    101 while(f < r) {
    102 u = q[f++];
    103 if(u.potA == C || u.potB == C) {
    104 printf("%d\n", u.stp);
    105 dfs(f-1);
    106 return ;
    107 }
    108 v.stp = u.stp + 1;
    109 v.pre = f-1;
    110 potA(v, u, r);
    111 potB(v, u, r);
    112
    113 }
    114 puts("impossible");
    115 }
    116
    117 int main() {
    118 //freopen("data.in", "r", stdin);
    119
    120 while(~scanf("%d%d%d", &A, &B, &C)) {
    121 bfs();
    122 }
    123 return 0;
    124 }


    poj 2531

    在discuss里看到有一种随机算法。貌似有些题目是可以用这种方法解的,比如Miller-Rabin测试,Pollard-rho因式分解都是概率型的。当数据不是很强时还是很值得用的。

    View Code
     1 #include <iostream>
    2 #include <cstring>
    3 #include <cstdio>
    4 #include <cmath>
    5 #include <cstdlib>
    6
    7 using namespace std;
    8
    9 const int N = 50;
    10 const int RAND = 100000;
    11
    12 bool sub[N];
    13 int mp[N][N];
    14 int n;
    15
    16 int solve() {
    17 int i, j, t, sum = 0, res = 0;
    18 memset(sub, 0, sizeof(sub));
    19
    20 for(i = 0; i < RAND; ++i) {
    21 t = rand()%n;
    22 sub[t] = !sub[t];
    23 for(j = 0; j < n; ++j) {
    24 if(sub[j] == sub[t]) {
    25 sum -= mp[j][t];
    26 } else {
    27 sum += mp[j][t];
    28 }
    29 }
    30 res = max(sum, res);
    31 }
    32 return res;
    33 }
    34
    35 int main() {
    36 //freopen("data.in", "r", stdin);
    37
    38 int i, j;
    39 while(~scanf("%d", &n)) {
    40 for(i = 0; i < n; ++i) {
    41 for(j = 0; j < n; ++j) {
    42 scanf("%d", &mp[i][j]);
    43 }
    44 }
    45 printf("%d\n", solve());
    46 }
    47 return 0;
    48 }


    POJ 1129

    图的着色问题。暴力回溯。详见:http://blog.csdn.net/suwei19870312/article/details/5282932

       

  • 相关阅读:
    Web用户的身份验证及WebApi权限验证流程的设计和实现
    开源工作流引擎CCFlow 学习专区
    Jquery Ajax方法传值到action
    再谈Jquery Ajax方法传递到action
    Windows下安装GTK+
    Tex使用
    配置Texmaker中文支持
    软件推荐列表(Recommand Software)
    CAD操作
    Package inputenc Error: Unicode char u8: not set up for use with LaTeX.
  • 原文地址:https://www.cnblogs.com/vongang/p/2410048.html
Copyright © 2011-2022 走看看