• F


    题目:Biggest Number

    题目大意:有一个R*C的矩阵,矩阵里面有1~9的数字(太好了不用处理前导0),或者是#(代表不能通过),先要从矩阵任意一点出发(之前英语抓鸡看成 了边界,英语差的孩纸伤不起啊>_<),只能往上下左右四个方向移动,每个格子不能重复走,到达矩阵内任意一点。把这条路径的数字连起来变成 一个很大的数字,求这个数字最大是什么。
    思路:DP?记忆化搜索?30个点噢,时间吃得消内存都吃不消啦。所以呢?搜索。还是超时啊?剪枝啊。
    剪 枝1:假设当前答案为ans,那么当我们走到一个点(x, y)的时候,作一个小小的搜索预判。假设现在能从(x, y)走到的点,我们都能到达,这是最好的情况。设从(x, y)能走到的点数为maxlen,那么如果从出发点走到(x, y)经过的格子,加上maxlen,都没有ans的长度大,那么不管从(x, y)怎么搜,我们都不能取代我们现在的ans(长才是王道懂不懂),那么直接回溯,不要这个点了。这个剪枝效力还是不错的,但是还是TLE,我试过了 QAQ。最近有点脑残,明明可以做一个数据测试一下非要交上去试一下……
    剪枝2:同剪枝1,假设当前答案为ans,那么当我们走到一个点(x, y)的时候,搜到maxlen(同剪枝1),如果从出发点走到(x, y)经过的格子,加上maxlen,大于ans的长度,我们就只能继续搜了……如果等于呢?那么就再作一个最好预期的答案。把从(x, y)能走到的所有格子,从大到小排好序(我的代码是从小到大排序然后从后面开始取的……),都接在当前走到(x, y)的后面,这是从(x, y)可能搜到的最好的答案,如果这个都比ans要小,那么我们也就没有必要往下搜了,果断回溯。
    PS:弄个结构体存答案很好写妥妥的。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <queue>
     6 using namespace std;
     7 typedef long long LL;
     8 
     9 const int MAXN = 33;
    10 
    11 struct Node {
    12     int a[MAXN], len;
    13     void clear() {
    14         len = 0;
    15     }
    16     void print() {
    17         //cout<<len<<endl;
    18         for(int i = 0; i < len; ++i) printf("%d", a[i]);
    19         printf("
    ");
    20     }
    21     bool operator < (const Node &rhs) const {
    22         if(len != rhs.len) return len < rhs.len;
    23         for(int i = 0; i < len; ++i)
    24             if(a[i] != rhs.a[i]) return a[i] < rhs.a[i];
    25         return false;
    26     }
    27 };
    28 
    29 int fx[] = {1, 0, -1, 0};
    30 int fy[] = {0, 1, 0, -1};
    31 
    32 Node ans, now, tmp;
    33 char mat[MAXN][MAXN];
    34 bool vis[MAXN][MAXN];
    35 bool vis2[MAXN][MAXN];
    36 int n, m;
    37 int can[MAXN];
    38 
    39 int maxlen(int x, int y) {
    40     queue<int> que; que.push(x * MAXN + y);
    41     int ret = 1;
    42     can[0] = mat[x][y] - '0';
    43     memset(vis2, 0, sizeof(vis2));
    44     vis2[x][y] = 1;
    45     while(!que.empty()) {
    46         int tmp = que.front(); que.pop();
    47         int nx = tmp / MAXN, ny = tmp % MAXN;
    48         for(int i = 0; i < 4; ++i) {
    49             int px = nx + fx[i], py = ny + fy[i];
    50             if(!isdigit(mat[px][py]) || vis[px][py] || vis2[px][py]) continue;
    51             vis2[px][py] = true;
    52             can[ret++] = mat[px][py] - '0';
    53             que.push(px * MAXN + py);
    54         }
    55     }
    56     return ret;
    57 }
    58 
    59 void dfs(int x, int y) {
    60     now.a[now.len++] = mat[x][y] - '0';
    61     vis[x][y] = true;
    62     for(int i = 0; i < 4; ++i) {
    63         int px = x + fx[i], py = y + fy[i];
    64         if(!isdigit(mat[px][py]) || vis[px][py]) continue;
    65         int wantlen = maxlen(px, py);
    66         if(now.len + wantlen < ans.len) continue;
    67         if(now.len + wantlen == ans.len) {
    68             sort(can, can + wantlen);
    69             tmp = now;
    70             for(int i = wantlen - 1; i >= 0; --i) tmp.a[tmp.len++] = can[i];
    71             if(tmp < ans) continue;
    72         }
    73         dfs(px, py);
    74     }
    75     if(ans < now) ans = now;
    76     --now.len;
    77     vis[x][y] = false;
    78 }
    79 
    80 int main() {
    81     while(scanf("%d%d", &n, &m) != EOF) {
    82         if(n + m == 0) break;
    83         memset(mat, 0, sizeof(mat));
    84         for(int i = 1; i <= n; ++i) scanf("%s", &mat[i][1]);
    85         ans.clear(); now.clear();
    86         for(int i = 1; i <= n; ++i) {
    87             for(int j = 1; j <= m; ++j)
    88                 if(isdigit(mat[i][j])) dfs(i, j);
    89         }
    90         ans.print();
    91     }
    92 }
  • 相关阅读:
    【Struts 动态表单】DynaActionForm
    【Struts 分派Action】DispatchAction
    【struts 报错】 No action config found for the specified url
    【Struts APP_PATH】StartSystemListener
    【Struts 编码】
    【Struts 基础案例】
    28. 实现 strStr()
    14. 最长公共前缀
    2. 两数相加
    15. 三数之和
  • 原文地址:https://www.cnblogs.com/scnuacm/p/3280329.html
Copyright © 2020-2023  润新知