现在的位置: 首页 > 综合 > 正文

USACO Section 5.1 Starry Night – 有点麻烦写的题..

2014年02月04日 ⁄ 综合 ⁄ 共 4004字 ⁄ 字号 评论关闭

     这道题应该一看~~基本思路就出来~~从左上角扫到右下角~~扫一个没更新过的连通块...就先与前面已经确定的比较...并且是翻成八种情况都来比较...若有符合的~~那么就确定这个连通块是前面哪个相同的...若无一符合~~就计数器++..发现新的连通块~~~但仔细想想...会好麻烦的感觉..

     我是这么处理的 :  

     1.记录前面的连通块..我就是记录了连通块上的某点坐标..因为只要知道了一个坐标~~从这个坐标开始DFS一次就能还原出这个连通块...

     2.从上一个思路出发..扫到新的连通块..要判断其是否经过各种旋转对称和前面某块相等..那么可以跟着前面通过一个坐标拓展出整个连通块的过程一起拓展...并且是按相应"相同"的方向..这样在拓展同时就能判断出两个块是不是相等..试想..若题目中只能完全相等才能说是一样(只有一种形态不翻转对称)..那不就是跟着前面拓展的路经同时在拓展当前...

     3.但是题目给出了8种方向..其实也好办..先人工判断出这八种形态的移动相对应的情况..也就是我手工打的turn这个表...比如说在1形态里拓展时向上走一步相等于2形态向左走一步,3形态向下走一步,4形态向左走一步,5形态向上走一步,6形态向左走一步,7形态向下走一步,8形态向右走一步.....前面的个连通块可以都假设成住一个形态..以一种形态的方式拓展~~我都是确定成了1型态~~这样就按这8个情况跟着前面某个确定好的连通块一起拓展..就可以判断出所有的情况是否有相同的.

     4.还有一点相当重要..同时拓展..除了相对方向要想同..更要起点相同...在记录前面连通块时我就是记录的连通块的最上面中最左边的点..而可以推出这个点在后面7个连通块中是在哪个位置...都是在连通块所有点的( MaxX or MinX , MaxY or MinY ) 上...人工判断下..所以我程序里写了那么长的判断更新...

     这道题主要就是看着他给的第一个图...来推的...算法简单..但写起来繁琐...要求思路严谨..

Program:

/*  
ID: zzyzzy12   
LANG: C++   
TASK: starry
*/      
#include<iostream>      
#include<istream>  
#include<stdio.h>     
#include<string.h>      
#include<math.h>      
#include<stack>
#include<map>
#include<algorithm>      
#include<queue>   
#define oo 2000000005  
#define ll long long  
#define pi (atan(2)+atan(0.5))*2 
using namespace std;
char arc[105][105];
struct node
{
    int x,y,m;      
}ans[28],StartPoint[10];
int turn[8][8][2]={  
                       {{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1}},
                       {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}},
                       {{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}},
                       {{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1}},   
                       {{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1}},
                       {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}},
                       {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}},
                       {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}},                                  
                  };
int W,H,num,k,m;
bool used[105][105];
void DFS1(int y,int x)
{
      int i;
      if (used[y][x] || arc[y][x]<'1') return; 
      used[y][x]=true; 
      if (y<StartPoint[1].y)
      {
             StartPoint[1].y=StartPoint[5].y=y;
             StartPoint[1].x=StartPoint[5].x=x;               
      }else
      if (y==StartPoint[1].y)
      {
             if (x<StartPoint[1].x) StartPoint[1].x=x;
             if (x>StartPoint[5].x) StartPoint[5].x=x;
      }//------------------1,5------------------
      if (y>StartPoint[3].y)
      {
             StartPoint[3].y=StartPoint[7].y=y;
             StartPoint[3].x=StartPoint[7].x=x;                               
      }else
      if (y==StartPoint[3].y)
      {
             if (x<StartPoint[7].x) StartPoint[7].x=x;
             if (x>StartPoint[3].x) StartPoint[3].x=x;
      }//------------------3,7------------------
      if (x<StartPoint[4].x)
      {
             StartPoint[4].y=StartPoint[6].y=y;
             StartPoint[4].x=StartPoint[6].x=x;                               
      }else
      if (x==StartPoint[4].x)
      {
             if (y<StartPoint[6].y) StartPoint[6].y=y;
             if (y>StartPoint[4].y) StartPoint[4].y=y;
      }//------------------4,6------------------
      if (x>StartPoint[2].x)
      {
             StartPoint[2].y=StartPoint[8].y=y;
             StartPoint[2].x=StartPoint[8].x=x;                               
      }else
      if (x==StartPoint[2].x)
      {
             if (y<StartPoint[2].y) StartPoint[2].y=y;
             if (y>StartPoint[8].y) StartPoint[8].y=y;
      }//------------------2,8------------------   
      ans[num+1].m++;  
      for (i=0;i<8;i++)
          DFS1(y+turn[0][i][1],x+turn[0][i][0]); 
      return;     
}
void DFS2(int y,int x,int p,int m)
{ 
      int i;
      if (arc[y][x]!='1') return;
      arc[y][x]='a'+p-1; 
      for (i=0;i<8;i++)
          DFS2(y+turn[0][i][1],x+turn[0][i][0],p,m+1);
      return;
} 
bool DFS(int y0,int x0,int y1,int x1)
{
      int i; 
      if (arc[y0][x0]<'1' || arc[y1][x1]<'1' || used[y0][x0]) return false;
      used[y0][x0]=true; 
      m--;
      if (!m) return true;
      for (i=0;i<8;i++)
          if (DFS(y0+turn[0][i][1],x0+turn[0][i][0],y1+turn[k][i][1],x1+turn[k][i][0])) return true; 
      return false;      
}
void getanswer()
{
      int x,y,p; 
      bool f;
      num=0;
      for (y=1;y<=H;y++)
        for (x=1;x<=W;x++)
           if (arc[y][x]=='1')
           {
                   f=false;
                   memset(used,false,sizeof(used));
                   StartPoint[1].y=StartPoint[4].x=StartPoint[5].y=StartPoint[6].x=oo;  
                   StartPoint[3].y=StartPoint[2].x=StartPoint[7].y=StartPoint[8].x=-oo; 
                   ans[num+1].m=0;
                   DFS1(y,x);      
                   for (p=1;p<=num;p++)
                   if (ans[p].m==ans[num+1].m)
                   {
                         for (k=0;k<8;k++)
                         {  
                                memset(used,false,sizeof(used));
                                m=ans[p].m;
                                if (DFS(ans[p].y,ans[p].x,StartPoint[k+1].y,StartPoint[k+1].x)) f=true;
                         }
                         if (f) break;
                   }
                   if (f) DFS2(y,x,p,1);
                   else
                   {
                         num++;
                         ans[num].x=x; ans[num].y=y; 
                         DFS2(y,x,num,1);
                   }                            
           }    
}
int main()  
{  
      freopen("starry.in","r",stdin);   
      freopen("starry.out","w",stdout); 
      int i,j;
      for (i=0;i<103;i++)
         for (j=0;j<103;j++)
             arc[i][j]='0';
      scanf("%d%d",&W,&H); 
      for (i=1;i<=H;i++)
         scanf("%s",arc[i]+1);
      getanswer();
      for (i=1;i<=H;i++)
         printf("%s\n",arc[i]+1);     
      return 0;     
}   

抱歉!评论已关闭.