POJ 1175 DFS || BFS



题意:题意很好懂的,看下图就知道了,就是连成一块的可以有八种相等的情况,给你一个0 1矩阵,让你将可以通过旋转相等的图形用相同字符表示,不同图形用不同字符表示。


然后,这道题我感觉相当考验编程基础,本身并没有什么算法,顶多就一个DFS或是BFS,我是用DFS写的。

思路:分三步

①找出图中所以联通的1,即两个for遍历矩阵,如果是1,就找出这一块

②每找到一块,就与之前的所有进行比较,如果之前存在相同的,就用之前的那个字符,  如果不存在相同的,就用一个新的字符。

③将这个字符给这一块赋值


最后就是输出


这只是我最开始构思的一个框架,其中有太多的细节了。最典型的就是,你怎么能将当前找到一块和之前的图形进行相比?   ----我的做法是直接暴力比,但是,暴力也是不那么容易写的好吧,我也不是纯暴力的。

首先,对于每一小块,我加了元素,即长,宽以及它的字符,很好理解吧,就是一块的一些基本元素。 

那么只有长宽都相等的块,才有可能进一步相等。所以我开了一个非常复杂的二维结构体数组,由长度宽度作为下标,里面的内容是相应长度宽度下的块。

每次比较就在这个二维数组中找。


这道题可能写出来后要花很长时间找bug,所以大家还是细心找一下,多编几组测试数据(不要看一组数据那么多0,1觉得不好编,其实还是挺好搞的,就找一个图形,把它八个相等的情况列出来),我的bug都是靠自己的测试数据找出来的。

然后,这个题很可能让你花半天或者一天,但是我觉得都是值得的,能够锻炼找bug的能力。


代码:

#include <stdio.h>
#include <string.h>

#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <deque>
#include <set>
#include <map>
using namespace std;
int row,col;
queue<int> q;
char s[104][104];
int visit[105][105];
int d1[]={-1,1,0,0,-1,-1,1,1},
    d2[]={0,0,-1,1,-1,1,-1,1};
int r1,c1,r2,c2;
struct spe
{
    char ch;
    char s[105][105];
};
struct spe2
{
    vector<spe> v;
};
spe2 p[104][104];
char ch = 'a',previ;

void dfs(int r,int c,char ch)
{
    q.push(r);
    q.push(c);
    s[r][c] = ch;
    visit[r][c] = 1;
    int rr,cc;
    r1 = min(r1,r);
    c1 = min(c1,c);
    r2 = max(r2,r);
    c2 = max(c2,c);
    for( int i = 0 ; i < 8 ; i++ )
    {
        rr = r+d1[i];
        cc = c+d2[i];
        if( visit[rr][cc] == 0 && s[rr][cc] == '1' )
            dfs(rr,cc,ch);
    }
}
bool judge( int h,int w )
{
    char ss[104][104];
    for( int i = r1 ; i <= r2 ; i++ )
        for( int j = c1 ; j <= c2 ; j++ )
            ss[i][j] = '0';
    int x,y;
    while( !q.empty() )
    {
        x = q.front();  q.pop();
        y = q.front();  q.pop();
        ss[x][y] = '1';
    }

    spe temp;
    temp.ch = ch;
    if( h <= w )
    {
        for( int i = 1 ,rr = r1; i <= h ; i++,rr++ )
        {
            for( int j = 1,cc = c1 ; j <= w ; j++,cc++ )
                temp.s[i][j] = ss[rr][cc];
            temp.s[i][w+1] ='\0';
        }
    }
    else
    {
        swap(h,w);
        for( int i = 1,cc = c1 ; i <= h ; i++,cc++ )
        {
            for( int j = 1,rr = r1 ; j <= w ; j++,rr++  )
                temp.s[i][j] = ss[rr][cc];
            temp.s[i][w+1] = '\0';
        }
    }
    if( p[h][w].v.size() == 0 )
    {
        if( h == w )
        {
            spe temp2;
            for( int i = 1 ; i <= h ; i++  )
                for( int j = 1 ; j <= w ; j++ )
                    temp2.s[i][j] = temp.s[j][i];
            temp2.ch = temp.ch;
            p[h][w].v.push_back(temp2);
        }
        p[h][w].v.push_back(temp);
        return true;
    }
    int len = p[h][w].v.size();
    for( int k = 0 ; k < len ; k++ )
    {
        previ = p[h][w].v[k].ch;
        bool flag = true;
        for( int i = 1 ; i <= h ; i++ )
            for( int j = 1 ; j <= w ; j++ )
                if( temp.s[i][j] != p[h][w].v[k].s[i][j] )
                {
                    flag = false;
                    goto first;
                }
        first:
            if( flag )
                return false;
        flag = true;
        for( int i = 1,rr = h ; i <= h ; i++,rr-- )
            for( int j = 1,cc = 1 ; j <= w ; j++,cc++ )
                if( temp.s[rr][cc] != p[h][w].v[k].s[i][j] )
                {
                    flag = false;
                    goto two;
                }
        two:
            if( flag )
                return false;
        flag = true;
        for( int i = 1,rr = 1 ; i <= h ; i++,rr++ )
            for( int j = 1,cc = w ; j <= w ; j++,cc-- )
                if( temp.s[rr][cc] != p[h][w].v[k].s[i][j] )
                {
                    flag = false;
                    goto three;
                }
        three:
            if( flag )
                return false;
                flag = true;
        for( int i = 1,rr = h ; i <= h ; i++,rr-- )
            for( int j = 1,cc = w ; j <= w ; j++,cc-- )
                if( temp.s[rr][cc] != p[h][w].v[k].s[i][j] )
                {
                    flag = false;
                    goto four;
                }
        four:
            if( flag )
                return false;
    }
    if( h == w )
        {
            spe temp2;
            for( int i = 1 ; i <= h ; i++  )
                for( int j = 1 ; j <= w ; j++ )
                    temp2.s[i][j] = temp.s[j][i];
            temp2.ch = temp.ch;
            p[h][w].v.push_back(temp2);
        }
    p[h][w].v.push_back(temp);
    return true;    //不与之前的重复
}
int main()
{
    memset(visit,0,sizeof visit);

    scanf("%d %d",&col,&row);
    for( int i = 1 ; i <= row ; i++ )
        scanf("%s",s[i]+1);



    for( int i = 1 ; i <= row ; i++ )
        for( int j = 1 ; j <= col ; j++ )
            if( s[i][j] == '1' && visit[i][j] == 0 )
            {
                r1 = r2 = i,c1 = c2 = j;
                dfs(i,j,'1');
                int h = r2-r1+1,w = c2-c1+1;
                if( judge(h,w) )
                    s[i][j] = ch++;
                else s[i][j] = previ;
            }
    memset(visit,0,sizeof visit);
    for( int i = 1 ; i <= row ; i++ )
        for( int j = 1 ; j <= col ; j++ )
            if( s[i][j] != '0' )
                dfs(i,j,s[i][j]);
    for( int i = 1 ; i <= row ; i++ )
        printf("%s\n",s[i]+1);


	return 0;
}
/*
5 7
10000
10000
11100
00000
10100
10000
11100
*/



猜你喜欢

转载自blog.csdn.net/qq_39627843/article/details/80250209