zoukankan      html  css  js  c++  java
  • 古韵之鹊桥相会

    jdoj1497-vijos1406古韵之鹊桥相会

        题目大意:给你一个m行n列的字母矩阵,有一个人,每一次可以将几个联通块打没。联通块的定义是两个挨着的字母,如果他们两个相同,那么就说他们两个是联通的。求:从上面到下面,最少打几次才可以到达。

        注释:n,m<21。

          想法:先说网上的主流题解。大部分的处理方式就是bfs求出联通块,将每一个联通块缩成一个点。最上面有一个大源点,下面有一个大源点,然后从上面到下面跑Dijkstra即可。在此说一说我yy的解法(网上好像也有)。就是dfs,暴力求出每两个点之间是否连通,设数组map[i1][j1][i2][j1]表示点(i1,j1)到点(i2,j2)的最短路。两个单独的挨着的点相同就是0,相异就是1,最后跑floyd 即可。时间复杂度$8cdot 10^6$可过。

        最后,附上丑陋的代码... ...

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 char s[25][25];
     6 int map[25][25][25][25];
     7 int n,m;
     8 void dfs(int a,int b)
     9 {
    10     if(a==m)
    11     {
    12         if(b==n) return;
    13         else
    14         {
    15             if(s[a][b+1]==s[a][b]) map[a][b][a][b+1]=map[a][b+1][a][b]=0;
    16             else map[a][b][a][b+1]=map[a][b+1][a][b]=1;
    17             dfs(a,b+1);
    18         }
    19     }
    20     else
    21     {
    22         if(b==n)
    23         {
    24             if(s[a+1][b]==s[a][b]) map[a][b][a+1][b]=map[a+1][b][a][b]=0;
    25             else map[a][b][a+1][b]=map[a+1][b][a][b]=1;
    26             dfs(a+1,1);
    27         }
    28         else
    29         {
    30             if(s[a+1][b]==s[a][b]) map[a][b][a+1][b]=map[a+1][b][a][b]=0;
    31             else map[a][b][a+1][b]=map[a+1][b][a][b]=1;
    32             if(s[a][b+1]==s[a][b]) map[a][b][a][b+1]=map[a][b+1][a][b]=0;
    33             else map[a][b][a][b+1]=map[a][b+1][a][b]=1;
    34             dfs(a,b+1);
    35         }
    36     }
    37 }
    38 int main()
    39 {
    40     scanf("%d%d",&m,&n);
    41     if(m==1)
    42     {
    43         printf("1
    ");
    44         return 0;
    45     }
    46     for(int i=1;i<=m;i++)
    47     {
    48         scanf("%s",s[i]+1);
    49     }
    50     memset(map,0x3f,sizeof(map));
    51     dfs(1,1);
    52     // for(int i=1;i<=m;i++) 
    53     // {
    54     //     for(int j=1;j<=n;j++)
    55     //     {
    56     //         printf("%d ",map[i][j][i+1][j]);
    57     //     }
    58     //     puts("");
    59     // }
    60     for(int k1=1;k1<=m;k1++) for(int k2=1;k2<=n;k2++)//floyd。
    61     for(int i1=1;i1<=m;i1++) for(int i2=1;i2<=n;i2++)
    62     for(int j1=1;j1<=m;j1++) for(int j2=1;j2<=n;j2++)
    63         map[i1][i2][j1][j2]=min(map[i1][i2][k1][k2]+map[k1][k2][j1][j2],map[i1][i2][j1][j2]);
    64     int minn=0x7f7f7f7f;//统计答案
    65     for(int head=1;head<=n;head++)
    66     {
    67         for(int foot=1;foot<=n;foot++)
    68         {    
    69             // printf("%d ",map[1][head][m][foot]);
    70             minn=min(map[1][head][m][foot],minn);
    71         }
    72         // puts("");
    73     }
    74     printf("%d",minn+1);//由于我从最上面到第一排的点并没有统计,所以需要+1,这也就是我为什么开始特判掉只有1行的情况。
    75 }

        小结,错误:忘记特判掉1了,这就gg了。

     

  • 相关阅读:
    Python的socket模块详解
    C语言中输入输出重定向,freopen的用法和实例
    JPG BMP TIF PNG 图像编码压缩率和编解码时间比较
    FFMPEG 内部YUV转RGB过程
    STL 中的数据结构
    FFmpeg 深度学习 livevideoStack 笔记
    Docker 编译tensorflow-1.14.0 静态库
    CMake 笔记
    Torch 学习
    Docker 学习笔记
  • 原文地址:https://www.cnblogs.com/ShuraK/p/8270236.html
Copyright © 2011-2022 走看看