• Codeforces 374 C. Travelling Salesman and Special Numbers (dfs、记忆化搜索)


    题目链接:Travelling Salesman and Special Numbers

    题意:

      给了一个n×m的图,图里面有'N','I','M','A'四种字符。问图中能构成NIMA这种序列最大个数(连续的,比如说NIMANIMA = 2)为多少,如果有环的话那么最大长度就是无穷。

    题解:

      哇,做了这题深深得感觉自己的dfs真的好弱。这题就是从N开始深搜,在深搜的过程中记录值。返回这个值加1.

     1 //#pragma comment(linker, "/stack:200000000")
     2 //#pragma GCC optimize("Ofast,no-stack-protector")
     3 //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
     4 //#pragma GCC optimize("unroll-loops")
     5 #include<bits/stdc++.h>
     6 using namespace std;
     7 const int MAX_N = 1e3+9;
     8 const int INF = 1e9+7;
     9 typedef pair<int,int> P;
    10 char vec[MAX_N][MAX_N];
    11 int mp[MAX_N][MAX_N];
    12 int res[MAX_N][MAX_N];
    13 int vis[MAX_N][MAX_N];
    14 int dir[4][2] = {-1,0,1,0,0,1,0,-1};
    15 int ans,flag,N,M,T;
    16 queue<P> que;
    17 vector<P> st;
    18 int dfs(int x,int y,int pos)
    19 {
    20     if(vis[x][y])
    21     {
    22         flag = false; return INF;
    23     }
    24     if(res[x][y]) return res[x][y];
    25     vis[x][y] = 1;
    26     int num =0;
    27     for(int i=0;i<4;i++)
    28     {
    29         int nx = x + dir[i][0];
    30         int ny = y + dir[i][1];
    31         if(nx>=0 && nx<N && ny>=0 && ny<M && mp[nx][ny] == (pos+1)%4 )
    32         {
    33             num = max(num,dfs(nx,ny,(pos+1)%4));
    34         }
    35     }
    36     res[x][y] = num+1;
    37     vis[x][y] = 0;
    38     return num+1;
    39 }
    40 int main()
    41 {
    42     cin>>N>>M;
    43     memset(vis,0,sizeof(vis));
    44     memset(res,0,sizeof(res));
    45     st.clear();
    46     for(int i=0; i<N; i++)
    47     {
    48         scanf("%s",vec[i]);
    49         for(int j=0; j<M; j++)
    50         {
    51             if(vec[i][j] == 'D') mp[i][j] = 0,st.push_back(P(i,j));
    52             else if(vec[i][j] == 'I') mp[i][j] = 1;
    53             else if(vec[i][j] == 'M') mp[i][j] = 2;
    54             else if(vec[i][j] == 'A') mp[i][j] = 3;
    55         }
    56     }
    57     int out = 0;
    58     flag = true;
    59     for(int i=0;i<st.size();i++)
    60     {
    61         if(res[st[i].first][st[i].second] != 0 || vis[st[i].first][st[i].second]) continue;
    62         int t = dfs(st[i].first,st[i].second,0);
    63         if(!flag) break;
    64         out = max(out,t/4);
    65     }
    66     if(flag)
    67     {
    68         if(out != 0) cout<<out<<endl;
    69         else cout<<"Poor Dima!"<<endl;
    70     }
    71     else cout<<"Poor Inna!"<<endl;
    72     return 0;
    73 }
    74 /*
    75 5 5
    76 DIADD
    77 DMADD
    78 DDDID
    79 AMMMD
    80 MIDAD
    81 
    82 answer: 3
    83 */
  • 相关阅读:
    线程安全的简单理解
    单链表 之 判断两链表是否交叉
    React组件间的通信
    input type=file美化
    Array.prototype.slice.call(arguments)
    ES5 数组方法every和some
    nodejs学习之表单提交(1)
    ES5 数组方法reduce
    ES5 数组方法map
    ES5 数组方法forEach
  • 原文地址:https://www.cnblogs.com/doggod/p/8424104.html
Copyright © 2020-2023  润新知