POJ 1230 Pass-Muraille

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int t,n,k,x,y,x1,y2,max_x,max_y,sum_s=0;
 5 //(x,y) (x1,y1)墙的两个端点,所有墙最大列坐标max_x,最大行坐标max_y,最少拆除墙面数为sum_s 
 6 int map[105][105];
 7 int main()
 8 {
 9     scanf("%d",&t);//测试用例数
10     while(t--)
11     {
12         memset(map,0,sizeof(map));
13         max_x=0;
14         max_y=0;
15         sum_s=0;
16         scanf("%d %d",&n,&k);
17         for(int i=1;i<=n;i++)
18         {
19             scanf("%d %d %d %d",&x,&y,&x1,&y2);//两个端点坐标
20             if(x>max_x)
21                 max_x=x;
22             if(x1>max_x)    
23                 max_x=x1;
24             if(y>max_y)
25                 max_y=y;//y=y2,所以只要一句
26             if(x<x1)//标记第i面墙 
27             {
28                 for(int j=x;j<=x1;j++)
29                     map[j][y]=i;    
30             } 
31             else
32             {
33                 for(int j=x1;j<=x;j++)
34                     map[j][y]=i;
35             }
36         }    
37         
38         for(int i=0;i<=max_x;i++)//从左到右扫描每一列 
39         {
40             int tem=0;//统计第i列中墙的格子数
41             for(int j=0;j<=max_y;j++)
42             {
43                 if(map[i][j]>0)
44                     tem++;
45             } 
46             int offset=tem-k;//墙多,则要拆offset面
47             if(offset>0)
48             {
49                 sum_s+=offset;
50                 while(offset--)
51                 {
52                     int max_s=0,max_bh;//最多的格子数,行数 
53                     for(int k=0;k<=max_y;k++)//搜索第i列每个有墙的格子 
54                     {
55                         if(map[i][k]>0)//若(i,k)为有墙格,则统计k行i列右方属于同堵墙的格子数tem_s 
56                         {
57                             int tem_s=0;
58                             for(int z=i+1;z<=max_x;z++)
59                             {
60                                 if(map[z][k]==map[i][k])
61                                     tem_s++;
62                             }
63                             if(max_s<tem_s)//该堵墙格子数最多,则记下 
64                             {
65                                 max_s=tem_s;
66                                 max_bh=k;
67                             }
68                          } 
69                     }
70                     //拆除含格子数最多的墙(第max_bh行上第i列开始的max_s个格子) 
71                     for(int a=i;a<=i+max_s;a++)
72                     {
73                         map[a][max_bh]=0;//拆除,不然会重复计数 
74                     }
75                 }
76             } 
77         }
78         printf("%d\n",sum_s);//输出最少拆除墙的面数 
79     } 
80     return 0;
81  } 

5.1.1

posted @ 2019-02-24 21:25  付玬熙  阅读(260)  评论(0编辑  收藏  举报