• zoj 1083 Frame Stacking


    其实就是一个拓补排序。(动态记录第i个之上的j存不存在,反过来就是第j个之下的i)

    首先确立每个框的位置(题目明确说了每一边都不会被完全覆盖)。/*可以通过搜索,搜索到该框的所有四个角*/||如果题目要求在严格一点,这个题目难度几何增加,在一定范围内是可算顺序的。

    检查边框的位置如果不是原来的字母,则说明原来的字母被现在的字母覆盖,得到一个局部大小关系(计算第j个下i的数量,0的话就确定下来这个j的位置了),接下来的就是拓补排序了。

    值得一提的是如果有多种可能的话,要按字典顺序逐个输出。(隐含的就是在循环遍历,默认条件就是字典顺序)

    #include<stdio.h>
    
    #include<string.h>
    
    int topo[26][26];
    
    char map[31][31];
    
    int xmax[26],xmin[26],ymax[26],ymin[26];/*每个字母框的四个角,即x的两个极值和y的两个极值*/
    
    char result[28];/*字母框掩盖的结果*/
    
    int h,w;
    
    int exist[26];/*创建一个可能的所有字母框,如果出现就记录它是否出现*/
    
    int used[26];/*已经确定的字母框*/
    
    int sum;
    
     
    
    void solve(int step)/*所有出现的框 解决第几个框*/
    
    {
    
        int s[26];
    
        int i,j;
    
     
    
        if(step==sum)/*如果解决的框到超出正常一个证明前面所有sum个框都确定了顺序*/
    
        {
    
            for(i=0;i<sum;i++)/*成功后输出结果*/
    
                printf("%c",result[i]);
    
            printf("
    ");
    
        }
    
               
    
        else
    
        {
    
            memset(s,0,sizeof(s));/*每次找到最底层的一个(除了已经确定下来的底层)*/
    
            for(i=0;i<26;i++)
    
                if(exist[i]&&!used[i])/*找到存在并且没有确定下来的框*/
    
                {
    
                    for(j=0;j<26;j++)
    
                        if(topo[j][i]==1&&!used[j])/*找到所有在i下面的框*/
    
                            s[i]++;/*统计在i框下面的框的个数*/
    
                }
    
            for(i=0;i<26;i++)/*按照字母顺序找满足条件的,那么最后就是有多个s=0,存储也是按字母顺序的*/
    
                if(exist[i]&& !used[i]&& s[i]==0)/*如果根据前面的寻找没有找到比i更低的框,那么就可以确定它就是第step*/
    
                {
    
                    result[step]=i+'A';
    
                    used[i]=1;
    
                    solve(step+1);
    
                    used[i]=0;
    
                }
    
        }
    
        return;
    
    }
    
     
    
    int main()
    
    {
    
        int i,j;
    
     
    
        while(scanf("%d",&h)!=EOF)
    
        {
    
            scanf("%d",&w);
    
            for(i=0;i<h;i++)
    
                scanf("%s",map[i]);
    
               
    
            memset(xmin,26,sizeof(xmin));
    
            memset(xmax,0,sizeof(xmax));
    
            memset(ymin,26,sizeof(ymin));
    
            memset(ymax,0,sizeof(xmax));
    
            memset(exist,0,sizeof(exist));
    
            sum=0;
    
            for(i=0;i<h;i++)
    
                for(j=0;j<w;j++)
    
                    if(map[i][j]!='.')/*该点有字母覆盖*/
    
                    {
    
                        if(!exist[map[i][j]-'A'])/*如果该字母没用出现过*/
    
                        {
    
                            exist[map[i][j]-'A']=1;/*记录该字母是否出现*/
    
                            sum++;/*统计不同字母框的个数*/
    
                        }
    
                        /*更新当前字母框的四个极值范围*/
    
                        if(j>xmax[map[i][j]-'A'])
    
                            xmax[map[i][j]-'A'] = j;
    
                        if(j<xmin[map[i][j]-'A'])
    
                            xmin[map[i][j]-'A'] = j;
    
                        if(i>ymax[map[i][j]-'A'])
    
                            ymax[map[i][j]-'A'] = i;
    
                        if(i<ymin[map[i][j]-'A'])
    
                            ymin[map[i][j]-'A'] = i;
    
                    }
    
     
    
            memset(topo,0,sizeof(topo));
    
            for(i=0;i<26;i++)
    
                if(exist[i])/*寻找出现过的字母框*/
    
                {
    
                       /*搜索每个字母框的四条边是否有其他框在他上面*/
    
                    for(j=xmin[i]; j<=xmax[i]; j++)/*从左下角搜索底边到右下角*/
    
                        if(map[ymin[i]][j] != i+'A')
    
                            topo[i][map[ymin[i]][j]-'A'] = 1;/*第i框有第j个框在他上面*/
    
                    for(j=xmin[i]; j<=xmax[i]; j++)/*从左上角搜索最高边到右上角*/
    
                        if(map[ymax[i]][j] != i+'A')
    
                            topo[i][map[ymax[i]][j]-'A'] = 1;
    
                    for(j=ymin[i]; j<=ymax[i]; j++)/*从左下角搜索左边到左上角*/
    
                        if(map[j][xmin[i]] != i+'A')
    
                            topo[i][map[j][xmin[i]]-'A'] = 1;
    
                    for(j=ymin[i]; j<=ymax[i]; j++)/*做右下角搜素右边到右上角*/
    
                        if(map[j][xmax[i]] != i+'A')
    
                            topo[i][map[j][xmax[i]]-'A'] = 1;
    
                }
    
     
    
            memset(used,0,sizeof(used));/*初始如何框都没有确定*/
    
            solve(0);
    
        }
    
        return 0;
    
    }
  • 相关阅读:
    常用控件的学习
    C# NOSQL 开源项目
    Js生成Guid
    通过sql语句附加数据库与启用sa账户
    Js 键值对实现
    sqlServer2000 安装备忘
    System.Reflection.ReflectionTypeLoadException: 无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性。
    关于ado.net连接池的一些分享(2)(原文出自:http://www.cnblogs.com/b42259626/articles/968460.html)
    关于ado.net连接池的一些分享(原文出自:http://www.cnblogs.com/rickie/archive/2004/10/02/48546.aspx)
    删除迅雷文件夹
  • 原文地址:https://www.cnblogs.com/woshijishu3/p/3631382.html
Copyright © 2020-2023  润新知