USACO_3_1_Shaping Regions

做一个矩形类,然后模拟放的过程,不过从最后放的矩形开始反序考虑

比如题目给出的样例,一开始放入颜色4的矩形,得到4与1相交部分,然后无论前面的矩形怎么放这一部分的颜色都是4,此时把其余颜色为1的部分分解为3个小矩形

然后再考虑放下颜色3的矩形,考虑剩余的白色矩形(颜色1),把每一个与3相交的做同样处理,即先把相交部分涂成颜色3,把这个白色矩形的其它部分分解为多个小矩形

直到放入第一个矩形为止

代码用一个RectangleList类来存放所有的白色矩形(由“白纸”分解而得)

Code
/**//*
ID: sdjllyh1
PROG: rect1
LANG: JAVA
complete date: 2009/1/8
author: LiuYongHui From GuiZhou University Of China
more articles: www.cnblogs.com/sdjls
*/


import java.io.*;
import java.util.*;

public class rect1
{
    
public static int n;//要放的矩形个数
    public static int[] l, r, t, b, c;//每个矩形的left,right,top,bottom,color
    public static int[] color = new int[2501];//每种颜色的面积

    
public static void main(String[] args) throws IOException
    
{
        init();
        run();
        output();
        System.exit(
0);
    }


    
private static void run()
    
{
        
//把白纸放入矩形链中
        RectangleList rects = new RectangleList(new Rectangle(t[0], b[0], l[0], r[0], 1));
        
//从最后放入的矩形开始依次考虑放入每一个矩形
        for (int i = n; i > 0; i--)
        
{
            
//获得放入的矩形
            Rectangle laying = new Rectangle(t[i], b[i], l[i], r[i], c[i]);
            
//获得与laying重叠的白色矩形
            List overlaps = rects.overlapRectangles(laying);
            Iterator it 
= overlaps.iterator();
            
//依次考虑每一个白色矩形
            while (it.hasNext())
            
{
                
//获得当前考虑的白色矩形
                Rectangle overlap = (Rectangle)it.next();
                
//laying的颜色面积增加,增加的面积是它与当前白色矩形重叠的面积
                color[laying.color] += laying.overlapArea(overlap);
                
//用laying把当前白色矩形分解为length个矩形,重叠部分不要
                Rectangle[] deRects = laying.decompose(overlap);
                
if (deRects != null)
                
{
                    
int length = deRects.length;
                    
//把分解得到的小矩形加入集合中
                    for (int j = 0; j < length; j++)
                    
{
                        rects.insertRect(deRects[j]);
                    }

                }

                
//从集合中删除当前白色矩形
                rects.deleteRect(overlap);
            }

        }

        
//计算白色面积
        color[1= r[0* t[0];
        
for (int i = 2; i <= 2500; i++)
        
{
            color[
1-= color[i];
        }


    }


    
private static void init() throws IOException
    
{
        BufferedReader f 
= new BufferedReader(new FileReader("rect1.in"));
        
char[] buff = new char[40000];
        f.read(buff);
        StringTokenizer st 
= new StringTokenizer(String.valueOf(buff));

        
int right = Integer.parseInt(st.nextToken());
        
int top = Integer.parseInt(st.nextToken());
        n 
= Integer.parseInt(st.nextToken());
        l 
= new int[n+1];
        r 
= new int[n+1];
        t 
= new int[n+1];
        b 
= new int[n+1];
        c 
= new int[n+1];

        r[
0= right;
        t[
0= top;

        
for (int i = 1; i <= n; i++)
        
{
            l[i] 
= Integer.parseInt(st.nextToken());
            b[i] 
= Integer.parseInt(st.nextToken());
            r[i] 
= Integer.parseInt(st.nextToken());
            t[i] 
= Integer.parseInt(st.nextToken());
            c[i] 
= Integer.parseInt(st.nextToken());
        }

        f.close();
    }


    
private static void output() throws IOException
    
{
        PrintWriter out 
= new PrintWriter(new BufferedWriter(new FileWriter("rect1.out")));
        
for (int i = 1; i <= 2500; i++)
        
{
            
if (color[i] > 0)
            
{
                out.print(i);
                out.print(
' ');
                out.println(color[i]);
            }

        }

        out.close();
    }

}

//矩形类
class Rectangle
{
    
private int top, bottom, left, right;//四条边坐标
    public int color;//颜色
    
    
public Rectangle(int top, int bottom, int left, int right, int color)
    
{
        
this.top = top;
        
this.bottom = bottom;
        
this.left = left;
        
this.right = right;
        
this.color = color;
    }

    
//分解rect矩形,获得多个小矩形,不要重叠部分
    public Rectangle[] decompose(Rectangle rect)
    
{
        Rectangle[] retList 
= null;
        
int color = rect.color;
        
int length;
        
//如果右在中间
        if ((rect.right <= this.right) && (rect.right >= this.left))
        
{
            
//如果左在中间
            if ((rect.left <= this.right) && (rect.left >= this.left))
            
{
                
//===右、左都在中间
                
//如果上在中间
                if ((rect.top <= this.top) && (rect.top >= this.bottom))
                
{
                    
//如果下在中间
                    if ((rect.bottom <= this.top) && (rect.bottom >= this.bottom))
                    
{
                        
//===上下左右都在中间
                    }

                    
else
                    
{
                        
//===左、右、上在中间、下不在
                        length = 1;
                        Rectangle[] dr 
= new Rectangle[length];
                        retList 
= dr;
                        
int[] l = new int[length];
                        
int[] r = new int[length];
                        
int[] t = new int[length];
                        
int[] b = new int[length];

                        l[
0= rect.left; r[0= rect.right; t[0= this.bottom; b[0= rect.bottom;

                        
for (int i = 0; i < length; i++)
                            dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                    }

                }
//如果下在中间
                else if ((rect.bottom <= this.top) && (rect.bottom >= this.bottom))
                
{
                    
//===左右下都在、上不在
                    length = 1;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= rect.left; r[0= rect.right; t[0= rect.top; b[0= this.top;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

                
else if ((rect.top >= this.top) && (rect.bottom <= this.bottom))
                
{
                    
//===左右在中间、上下在两边
                    length = 2;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= rect.left; r[0= rect.right; t[0= rect.top; b[0= this.top;
                    l[
1= rect.left; r[1= rect.right; t[1= this.bottom; b[1= rect.bottom;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

            }

            
else
            
{
                
//===右在中间,左不在中间
                
//如果上在中间
                if ((rect.top <= this.top) && (rect.top >= this.bottom))
                
{
                    
//如果下在中间
                    if ((rect.bottom <= this.top) && (rect.bottom >= this.bottom))
                    
{
                        
//===右、上、下在中间、左不在
                        length = 1;
                        Rectangle[] dr 
= new Rectangle[length];
                        retList 
= dr;
                        
int[] l = new int[length];
                        
int[] r = new int[length];
                        
int[] t = new int[length];
                        
int[] b = new int[length];

                        l[
0= rect.left; r[0= this.left; t[0= rect.top; b[0= rect.bottom;

                        
for (int i = 0; i < length; i++)
                            dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                    }

                    
else
                    
{
                        
//===右、上在,左、下不在
                        length = 2;
                        Rectangle[] dr 
= new Rectangle[length];
                        retList 
= dr;
                        
int[] l = new int[length];
                        
int[] r = new int[length];
                        
int[] t = new int[length];
                        
int[] b = new int[length];

                        l[
0= rect.left; r[0= this.left; t[0= rect.top; b[0= rect.bottom;
                        l[
1= this.left; r[1= rect.right; t[1= this.bottom; b[1= rect.bottom;

                        
for (int i = 0; i < length; i++)
                            dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                    }

                }

                
else if ((rect.bottom <= this.top) && (rect.bottom >= this.bottom))
                
{
                    
//===右、下在中间,上、左不在中间
                    length = 2;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= rect.left; r[0= this.left; t[0= rect.top; b[0= rect.bottom;
                    l[
1= this.left; r[1= rect.right; t[1= rect.top; b[1= this.top;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

                
else
                
{
                    
//===右在、上下左不在
                    length = 3;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= rect.left; r[0= this.left; t[0= rect.top; b[0= rect.bottom;
                    l[
1= this.left; r[1= rect.right; t[1= rect.top; b[1= this.top;
                    l[
2= this.left; r[2= rect.right; t[2= this.bottom; b[2= rect.bottom;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

            }

        }

        
else if ((rect.left <= this.right) && (rect.left >= this.left))
        
{
            
//===右不在中间、左在中间
            
//如果上在中间
            if ((rect.top <= this.top) && (rect.top >= this.bottom))
            
{
                
//===左、上在中间,右不在
                
//如果下在中间
                if ((rect.bottom <= this.top) && (rect.bottom >= this.bottom))
                
{
                    
//===左、上、下在中间,右不在
                    length = 1;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= this.right; r[0= rect.right; t[0= rect.top; b[0= rect.bottom;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

                
else
                
{
                    
//===左上在,右下不在
                    length = 2;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= rect.left; r[0= this.right; t[0= this.bottom; b[0= rect.bottom;
                    l[
1= this.right; r[1= rect.right; t[1= rect.top; b[1= rect.bottom;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

            }

            
else if ((rect.bottom <= this.top) && (rect.bottom >= this.bottom))
            
{
                
//===下、左在中间,右、上不在中间
                length = 2;
                Rectangle[] dr 
= new Rectangle[length];
                retList 
= dr;
                
int[] l = new int[length];
                
int[] r = new int[length];
                
int[] t = new int[length];
                
int[] b = new int[length];

                l[
0= rect.left; r[0= this.right; t[0= rect.top; b[0= this.top;
                l[
1= this.right; r[1= rect.right; t[1= rect.top; b[1= rect.bottom;

                
for (int i = 0; i < length; i++)
                    dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
            }

            
else
            
{
                
//===左在,右上下不在
                length = 3;
                Rectangle[] dr 
= new Rectangle[length];
                retList 
= dr;
                
int[] l = new int[length];
                
int[] r = new int[length];
                
int[] t = new int[length];
                
int[] b = new int[length];

                l[
0= rect.left; r[0= this.right; t[0= rect.top; b[0= this.top;
                l[
1= rect.left; r[1= this.right; t[1= this.bottom; b[1= rect.bottom;
                l[
2= this.right; r[2= rect.right; t[2= rect.top; b[2= rect.bottom;

                
for (int i = 0; i < length; i++)
                    dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
            }

        }

        
else
        
{
            
//===左右都不在中间
            if ((rect.top <= this.top) && (rect.top >= this.bottom))
            
{
                
//===如果上在、左右不在
                if ((rect.bottom <= this.top) && (rect.bottom >= this.bottom))
                
{
                    
//===上、下在,左右不在
                    length = 2;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= rect.left; r[0= this.left; t[0= rect.top; b[0= rect.bottom;
                    l[
1= this.right; r[1= rect.right; t[1= rect.top; b[1= rect.bottom;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

                
else
                
{
                    
//===上在,左右下不在
                    length = 3;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= rect.left; r[0= this.left; t[0= rect.top; b[0= rect.bottom;
                    l[
1= this.left; r[1= this.right; t[1= this.bottom; b[1= rect.bottom;
                    l[
2= this.right; r[2= rect.right; t[2= rect.top; b[2= rect.bottom;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

            }

            
else
            
{
                
//===左右上都不在
                if ((rect.bottom <= this.top) && (rect.bottom >= this.bottom))
                
{
                    
//===下在,左右上不在
                    length = 3;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= rect.left; r[0= this.left; t[0= rect.top; b[0= rect.bottom;
                    l[
1= this.left; r[1= this.right; t[1= rect.top; b[1= this.top;
                    l[
2= this.right; r[2= rect.right; t[2= rect.top; b[2= rect.bottom;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

                
else
                
{
                    
//===上下左右都不在
                    length = 4;
                    Rectangle[] dr 
= new Rectangle[length];
                    retList 
= dr;
                    
int[] l = new int[length];
                    
int[] r = new int[length];
                    
int[] t = new int[length];
                    
int[] b = new int[length];

                    l[
0= rect.left; r[0= this.left; t[0= rect.top; b[0= rect.bottom;
                    l[
1= this.left; r[1= this.right; t[1= rect.top; b[1= this.top;
                    l[
2= this.right; r[2= rect.right; t[2= rect.top; b[2= rect.bottom;
                    l[
3= this.left; r[3= this.right; t[3= this.bottom; b[3= rect.bottom;

                    
for (int i = 0; i < length; i++)
                        dr[i] 
= new Rectangle(t[i], b[i], l[i], r[i], color);
                }

            }

        }

        
return retList;
    }

    
//判断矩形是否重叠
    public boolean isOverlap(Rectangle rect)
    
{
        
int l = Math.max(this.left, rect.left);
        
int r = Math.min(this.right, rect.right);
        
if (l >= r)
            
return false;

        
int b = Math.max(this.bottom, rect.bottom);
        
int t = Math.min(this.top, rect.top);
        
if (b >= t)
            
return false;

        
return true;
    }

    
//计算重叠面积
    public int overlapArea(Rectangle rect)
    
{
        
int l = Math.max(this.left, rect.left);
        
int r = Math.min(this.right, rect.right);
        
if (l >= r)
            
return 0;

        
int b = Math.max(this.bottom, rect.bottom);
        
int t = Math.min(this.top, rect.top);
        
if (b >= t)
            
return 0;

        
int wide = r - l;
        
int hight = t - b;

        
return wide * hight;
    }

}
;//class Rectangle end

//矩形链表
class RectangleList
{
    
private List listRect = new ArrayList();

    
public RectangleList(Rectangle rect)
    
{
        listRect.add(rect);
    }

    
//插入矩形
    public void insertRect(Rectangle rect)
    
{
        listRect.add(rect);
    }

    
//删除矩形
    public void deleteRect(Rectangle rect)
    
{
        listRect.remove(rect);
    }

    
//返回链中所有与rect重叠的矩形
    public List overlapRectangles(Rectangle rect)
    
{
        List retList 
= new ArrayList();

        Iterator it 
= listRect.iterator();
        
while (it.hasNext())
        
{
            Rectangle r 
= (Rectangle)it.next();
            
if (rect.isOverlap(r))
            
{
                retList.add(r);
            }

        }


        
return retList;
    }

}
;//class RectangleList end

你可能感兴趣的:(USACO_3_1_Shaping Regions)