zoukankan      html  css  js  c++  java
  • TopCoder[SRM587 DIV 1]:ThreeColorability(900)

    Problem Statement

        

    There is a H times W rectangle divided into unit cells. The rows of cells are numbered 0 to H-1 from top to bottom, and the columns are numbered 0 to W-1 from left to right. The corners of cells are called lattice points. By definition, there are (H+1)*(W+1) lattice points in our rectangle.

    Each of the four edges of each cell is painted white. Additionally, in some cells exactly one of the two diagonals is painted white. In the remaining cells no diagonal is painted white yet. Later, you are going to paint exactly one of the diagonals white in each of these cells.

    Once you are done painting the diagonals, your next goal will be to color each of the lattice points using one of three available colors: red, green, or blue. There is only one constraint: adjacent lattice points are not allowed to share the same color.

    Two lattice points are called adjacent if they are connected by a white line segment. (In other words, consecutive corners of a cell are always adjacent, opposite corners of a cell are adjacent if and only if they are connected by a painted diagonal, and no other pairs of lattice points are adjacent.)

    Obviously, you need to paint the missing diagonals in such a way that there will be a valid coloring of lattice points, if possible.

    You are given a vector <string> cells with H elements, each consisting of W characters. If cells[i][j] is 'N', there is a diagonal line from the top left to the bottom right corner in the cell in row i, column j. If cells[i][j] is 'Z', there is a diagonal line from the top right to the bottom left corner in the cell in row i, column j. If cells[i][j] is '?', there is no diagonal yet in the cell in row i, column j.

    If it is impossible to fill in the missing diagonals in such a way that there will be a valid coloring of all lattice points, return an empty vector <string>. Otherwise, return a vector <string> that represents the rectangle with all the missing diagonals filled in. I.e., the return value must be obtained from cells by replacing each '?' by either 'N' or 'Z'. The return value must represent a rectangle for which a valid coloring of its lattice points exists. If there are multiple possibilities, return the lexicographically smallest one.

    Definition

        
    Class: ThreeColorability
    Method: lexSmallest
    Parameters: vector <string>
    Returns: vector <string>
    Method signature: vector <string> lexSmallest(vector <string> cells)
    (be sure your method is public)

    Limits

        
    Time limit (s): 2.000
    Memory limit (MB): 64

    Notes

    - Given two different vector <string>s A and B with the same number of elements, find the smallest index i such that A[i] and B[i] differ. If A[i] < B[i] we say that A is lexicographically smaller than B and vice versa.

    Constraints

    - cells will contain between 1 and 50 elements, inclusive.
    - Each element of cells will contain between 1 and 50 characters, inclusive.
    - All elements of cells will contain the same number of characters.
    - Each character of cells will be either 'N' or 'Z' or '?'.

    Examples

    0)  
        
    {"Z"}
    Returns: {"Z" }
    The given rectangle and a possible coloring is as follows.

    1)  
        
    {"??", "?N"}
    Returns: {"NN", "NN" }

    2)  
        
    {"ZZZ", "ZNZ"}
    Returns: { }
     
    3)  
        
    {"N?N??NN","??ZN??Z","NN???Z?","ZZZ?Z??","Z???NN?","N?????N","ZZ?N?NN"}
    Returns: { }
     
    4)  
        
    {"ZZZZ","ZZZZ","ZZZZ"}
    Returns: {"ZZZZ", "ZZZZ", "ZZZZ" }
     

    题意:给定一个网格图,为每个格子安排对角线(有些格子已经安排好),使得新图可以被用三种颜色染色(被一条边相连的两个点不能染同一种颜色)。两种对角线用'Z'与'N'表示。

    题解:

    画图找规律,可以发现,在相邻的四个格子中(即3*3的格点),'Z'的数量为偶数。

    由此可以推得,在一个合法的图中,一行格子的对角线安排如果不与相邻的行完全相同,就与相邻的行完全相反。

    即不管在哪一行,第i列与第j列格子对角线安排是否相同的关系都是一样的。

    即我们可以用已知的每一行内的关系,通过并查集处理出第一行各格子的关系。

    然后在满足原本安排方案的情况下,求出一种字典序最小的安排方案。

    代码:

     1 int fa[200],a[200][200],n,m;
     2 int getf(int x)
     3 {
     4     if(fa[x]!=x)fa[x]=getf(fa[x]);
     5     return fa[x];
     6 }
     7 int hb(int xx,int yy)
     8 {
     9     int x=getf(xx),y=getf(xx+m),z=getf(yy),w=getf(yy+m);
    10     if((x==w)or(y==z))return 1;
    11     fa[x]=z; fa[y]=w; return 0;
    12 }
    13 int qf(int xx,int yy)
    14 {
    15     int x=getf(xx),y=getf(xx+m),z=getf(yy),w=getf(yy+m);
    16     if((x==z)or(y==w))return 1;
    17     fa[x]=w; fa[y]=z; return 0;
    18 }
    19 int pd(char x)
    20 { if(x=='N')return 1; if(x=='Z')return -1; return 0; }
    21 class ThreeColorability
    22 {
    23     public:
    24     vector <string> lexSmallest(vector <string> cells)
    25     {
    26         //$CARETPOSITION$
    27         vector<string>ans;
    28         n=cells.size(); m=cells[0].size();
    29         for(int i=0;i<m;i++)fa[i]=i,fa[i+m]=i+m;
    30         for(int i=0;i<n;i++)
    31         for(int j=0;j<m-1;j++)
    32         if(cells[i][j]!='?')
    33         {
    34             for(int k=j+1;k<m;k++)
    35             if(cells[i][k]!='?')
    36             {
    37                 int flag;
    38                 if(cells[i][j]==cells[i][k])flag=hb(j,k);else flag=qf(j,k);
    39                 if(flag==1)return ans;
    40             }
    41         }
    42         for(int j=0;j<m;j++)
    43         {
    44             int t=pd(cells[0][j]);
    45             if(t!=0)
    46             {
    47                 int x=getf(j),y=getf(j+m);
    48                 for(int k=0;k<m;k++)
    49                 {
    50                     if(getf(k)==x)a[0][k]=t;else
    51                     if(getf(k)==y)a[0][k]=-t;
    52                 }
    53             }
    54         }
    55         for(int j=0;j<m;j++)
    56         if(a[0][j]==0)
    57         {
    58             int x=getf(j),y=getf(j+m);
    59             for(int k=0;k<m;k++)
    60             {
    61                 if(getf(k)==x)a[0][k]=1;else
    62                 if(getf(k)==y)a[0][k]=-1;
    63             }
    64         }
    65         for(int i=1;i<n;i++)
    66         {
    67             int x=0;
    68             for(int j=0;j<m;j++)if(pd(cells[i][j])!=0)
    69             { if(pd(cells[i][j])==a[i-1][j])x=1;else x=-1; break; }
    70             if(x==0){ if(a[i-1][0]==1)x=1;else x=-1; }
    71             for(int j=0;j<m;j++)a[i][j]=a[i-1][j]*x;
    72         }
    73         for(int i=0;i<n;i++)
    74         {
    75             string s; s.clear();
    76             for(int j=0;j<m;j++)if(a[i][j]==1)s=s+'N';else s=s+'Z';
    77             ans.push_back(s);
    78         }
    79         return ans;
    80     }    
    81 };
    View Code
  • 相关阅读:
    fetch jsonp请求接口
    mysql explain执行计划详解
    MySQL主从复制与读写分离 --非原创
    C#修改文件或文件夹的权限,为指定用户、用户组添加完全控制权限
    Mysql有没有语法可以在增加列前进行判断该列是否存在
    .net4.0注册到IIS ,重新注册IIS ,iis注册
    C#操作IIS程序池及站点的创建配置
    .net C# 对虚拟目录IIS的操作
    I​n​n​o​ ​s​e​t​u​p​ ​常​用​修​改​技​巧
    innosetup语法详解
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6699526.html
Copyright © 2011-2022 走看看