zoukankan      html  css  js  c++  java
  • poj1128 dfs+拓扑

    http://poj.org/problem?id=1128

    题目大意:
    如图有5个9*8的区域
    [拓扑排序+构图]poj <wbr>1128:Frame <wbr>Stacking

    上面分别存在由相同的字母围成的长方形;
    把他们依次覆盖起来,便形成了如下的图形
    [拓扑排序+构图]poj <wbr>1128:Frame <wbr>Stacking

    //////可以大致看出有的字母方框的字母被另外的一些字母覆盖了起来
    输出从下到上被覆盖的字母的顺序,例如此图为EDABC
    大致思路:这种问题稍稍思考便知道是一个拓扑排序的问题,但是真正编码后便感觉还缺了一些东西,对,就是建图!模版谁都会用,但是真正牛人就是牛在知道如何搭建使用模版的环境。如图怎么在原来杂乱无章的map基础上归纳出字母之间的上下级关系便是这道题目的重点所在。
    做法是这样:
    依次遍历整个map,找到一个字母后便针对这个字母,求出其所在方框的范围,并找出的其范围内的其他字母,建立指向原先字母的边。对图中所有字母重复这个过程,便得到了一个有向图,并对这个有向图拓扑排序,便得到了答案
     
     
     
     
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 char str[100];
     6 char map[100][100];
     7 bool vis[100];
     8 int in[100],edge[100][100],r,c;
     9 int lx,uy,rx,dy,num;
    10 void find(int y,int x){
    11     char ch=map[y][x];
    12     lx=uy=10000;
    13     rx=dy=-1;
    14     for(int i=0;i<r;i++){
    15         for(int j=0;j<c;j++){
    16             if(map[i][j]==ch){
    17                      if(i<uy)uy=i;
    18                      if(i>dy)dy=i;
    19                      if(j<lx)lx=j;
    20                      if(j>rx)rx=j;
    21             }
    22         }
    23     }
    24 }
    25 void buildmap(){
    26     int i,j,k;
    27     num=0;
    28     for(i=0;i<r;i++){
    29         for(j=0;j<c;j++){
    30             if(map[i][j]=='.'||in[map[i][j]-'A']!=-1)continue;
    31             num++;
    32             in[map[i][j]-'A']=0;
    33             char ch=map[i][j];
    34             find(i,j);
    35             for(k=lx;k<=rx;k++){
    36                 if(map[uy][k]!=ch)edge[ch-'A'][map[uy][k]-'A']=1;
    37                 if(map[dy][k]!=ch)edge[ch-'A'][map[dy][k]-'A']=1;
    38             }
    39             for(k=uy;k<=dy;k++){
    40                 if(map[k][lx]!=ch)edge[ch-'A'][map[k][lx]-'A']=1;
    41                 if(map[k][rx]!=ch)edge[ch-'A'][map[k][rx]-'A']=1;
    42             }
    43         }
    44     }
    45     for(i=0;i<27;i++){
    46         for(j=0;j<27;j++){
    47             if(edge[i][j])
    48                 in[j]++;
    49         }
    50     }
    51 }
    52 void dfs(char *s,int cnt){
    53     if(cnt==num){
    54         printf("%s
    ",str);
    55         return;
    56     }
    57     int i,j;
    58     for(i=0;i<27;i++){
    59         if(in[i]==0&&!vis[i]){
    60             str[cnt]=i+'A';
    61             vis[i]=1;
    62             for(j=0;j<27;j++){
    63                 if(edge[i][j])--in[j];
    64             }
    65             dfs(s,cnt+1);
    66             vis[i]=0;
    67             for(j=0;j<27;j++){
    68                 if(edge[i][j])++in[j];
    69             }
    70         }
    71     }
    72 }
    73 int main(){
    74     int i,j;
    75     while(scanf("%d%d",&r,&c)!=EOF){
    76         memset(str,0,sizeof(str));
    77         memset(vis,0,sizeof(vis));
    78         memset(in,-1,sizeof(in));
    79         memset(edge,0,sizeof(edge));
    80         for(i=0;i<r;i++)scanf("%s",map[i]);
    81         buildmap();
    82         dfs(str,0);
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    装饰器的用法——用装饰器来记录函数被调用的次数
    类和对象(上) C++
    数据结构—树(二叉树)
    数据结构—顺序表
    c++入门

    Cypress博客
    自动化测试框架总结2
    前端测试框架Jest总结
    关于redux和react书籍源码系列代码
  • 原文地址:https://www.cnblogs.com/SSYYGAM/p/4509311.html
Copyright © 2011-2022 走看看