随笔-141  评论-9  文章-3  trackbacks-0
FloodFill遍历,对于个每个图形,分别进行旋转、对称total7种操作,然后在hash table中找是否存在。

/*
ID: lorelei3
TASK: starry
LANG: C++
*/


#include 
<fstream>
#include 
<queue>
#include 
<memory.h>

using namespace std;

const int MAX = 105;
const int MAXT = 505;
const int dx[] ={1,1,0,-1,-1,-101};
const int dy[] ={0,1,110,-1,-1,-1};
const int INF = 0x7FFFFFF;

struct Point{
    
int x,y;
}
;

struct Hashcode{
    
int width,height;
    
char mark;
    
bool code[MAX][MAX];
    Hashcode()

        memset(code, 
falsesizeof(code));
    }

}
;

ifstream fin(
"starry.in");
ofstream fout(
"starry.out");

char map[MAX][MAX];
char newmark = 'a';

int cnt;
Hashcode ht[MAXT];

int w,h;
void input(){
    fin
>>w>>h;
    fin.
get();
    
for(int i=0; i<h; ++i){
        
for(int j=0; j<w; ++j){
            map[i][j] 
= (char)fin.get();
        }

        fin.
get();
    }

}


void flip(const Hashcode in, Hashcode &out){
    
out.height = in.height;
    
out.width = in.width;
    
out.mark = in.mark;
    
for(int i=0; i<in.width; ++i)
        
for(int j=0; j<in.height; ++j)
            
out.code[i][in.height-1-j]=in.code[i][j];
}


void turn(const Hashcode in, Hashcode &out){
    
out.height=in.width;
    
out.width=in.height;
    
out.mark = in.mark;
    
for(int i=0; i<in.width; ++i)
        
for(int j=0; j<in.height; ++j)
            
out.code[j][in.width-1-i]=in.code[i][j];
}


void transform(const Hashcode in, Hashcode &outint op){
    
    
if(op==0){
        
out = in;
        
return;
    }


    
if(op==1){
        turn(
inout);
        
return;
    }


    
if(op==2){
        Hashcode t;
        turn(
in, t);
        turn(t, 
out);
        
return;
    }


    
if(op==3){
        Hashcode t1,t2;
        turn(
in, t1);
        turn(t1, t2);
        turn(t2, 
out);
        
return;
    }


    
if(op==4){
        flip(
inout);
        
return;
    }


    
if(op==5){
        Hashcode t;
        flip(
in, t);
        turn(t, 
out);
    }


    
if(op==6){
        Hashcode t1,t2;
        flip(
in, t1);
        turn(t1, t2);
        turn(t2, 
out);

    }


    
if(op==7){
        Hashcode t1,t2,t3;
        flip(
in, t1);
        turn(t1, t2);
        turn(t2, t3);
        turn(t3, 
out);
    }

}


int  findhash(Hashcode code){
    
for(int k=0; k<cnt; ++k){
        
if(code.height!=ht[k].height || code.width!=ht[k].width)
            
continue;
        
bool flag = true;
        
for(int i=0; i<code.width; ++i)
            
for(int j=0; j<code.height; ++j)
                
if(code.code[i][j] != ht[k].code[i][j]){
                    flag 
= false;
                    
break;
                }

        
if(flag==true)
            
return k;
    }

    
return -1;
}


void floodfill(int x, int y){
    
int i,j, ii, jj;

    Point st;
    st.x 
= x, st.y =y;

    
int minx=INF, miny=INF, maxx=0, maxy=0;

    queue
<Point> Q;
    Q.push(st);
    
while(!Q.empty()){
        Point pt 
= Q.front();
        Q.pop();
        map[pt.x][pt.y]
='2';

        
if(pt.x<minx) minx=pt.x;
        
if(pt.x>maxx) maxx=pt.x;
        
if(pt.y<miny) miny=pt.y;
        
if(pt.y>maxy) maxy=pt.y;

        
for(int i=0; i<8++i){
            Point t;
            t.x
=pt.x+dx[i];
            t.y
=pt.y+dy[i];
            
            
if(t.x<0||t.x>h)continue;
            
if(t.y<0||t.y>w)continue;

            
if(map[t.x][t.y]=='1'){
                map[t.x][t.y]
='2';
                Q.push(t);
            }

        }

    }


    Hashcode hash;
    hash.width 
= maxx-minx+1;
    hash.height 
= maxy-miny+1;
    
for(i=minx, ii=0; i<=maxx; ++i, ++ii)
        
for(j=miny, jj=0; j<=maxy; ++j,++jj)
            
if(map[i][j]=='2')
                hash.code[ii][jj]
=true;
            
else
                hash.code[ii][jj]
=false;

    
char mark=0;
    
for(int op=0; op<8++op){
        Hashcode code;
        transform(hash, code, op);
        
int k = findhash(code);
        
if(k!=-1){
            mark 
= ht[k].mark;
            
break;
        }

    }


    
if(mark==0){
        mark 
= (char)newmark++;
        hash.mark 
= mark;
        ht[cnt
++]=hash;
    }


    
for(i=minx; i<=maxx; ++i)
        
for(j=miny; j<=maxy; ++j)
            
if(map[i][j]=='2')
                map[i][j]
=mark;

}


void solve(){
    
for(int i=0; i<h; ++i)
        
for(int j=0; j<w; ++j)
            
if(map[i][j]=='1')
                floodfill(i,j);
}


void output(){

    
for(int i=0; i<h; ++i){
        
for(int j=0; j<w; ++j)
            fout
<<map[i][j];
        fout
<<endl;
    }

}


int main(){

    input();

    solve();

    output();

    
return 0;
}



posted on 2011-02-08 13:01 小阮 阅读(313) 评论(0)  编辑 收藏 引用 所属分类: USACO

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理