【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 104870
  • 排名 - 233

最新评论

阅读排行榜

评论排行榜

背景 Background
笨笨:哼哼哼……今天要干点坏事~
路人甲:0o。(-. - )
笨笨:哈哈哈……看我怎么干坏事吧~(炸弹已安置)
路人甲:啊?!什么什么?你刚刚说什么?
笨笨:切,不理你了……闪人……

描述 Description
现在笨笨有多个正方形的区域要炸——用那经典的按密码的小方块……在这些区域中原有多个引爆点,但是这些引爆点只能引爆所在的一个方形区域(区域大小不限,具体看样例),并且不能和另一个引爆点同时引爆同一个区域。笨笨想知道,在所有的正方形区域中,有哪些是可以一次炸完的。

输入格式 Input Format
输入第一行是正方形区域的个数,为了不太累,个数在50个以内。
然后是对这些正方形区域的描述,各个描述格式如下:
第一行两个数L(0<L<25),N(N>0)。L表示正方形区域的边长,N表示该正方形区域内引爆点个数。
接下来N行每行两个数X,Y(0<x,y<=L)表示在横坐标X,纵坐标Y的地方有一个引爆点。

输出格式 Output Format
对于每一个正方形区域,输出一个"Yes"或一个"No",表示能否一次引爆这个区域。
对于每个正方形区域输出一行。

样例输入 Sample Input
1
5 8
2 4
3 3
3 4
3 5
4 2
4 4
4 5
5 5

样例输出 Sample Output
Yes

时间限制 Time Limitation
1s

对于样例:
引爆点分布图
+-----+
|.....|
|...*.|
|..***|
|.*.**|
|....*|
+-----+

区域分割图
+-----+
|11122|
|11122|
|11134|
|55667|
|55668|
+-----+
在这样的分割下,这个正方形区域可以被一次引爆。


分析:
dfs搜索题。
1.如果这个框中,没有炸弹,那么继续拉大正方形框。
2.如果这个框中有一个炸弹,那就可以递归了,当做这个框里的格子全被这个炸弹炸掉了。
3.如果这个正方形框里有多于一个炸弹,或者这个正方形框里的某些格子以前已经被标记过了(这个地方只要判断一个格子就可以了,程序中我会做标注),那就无解回溯(记得要把这次搜索的标记改回来)


【参考程序】:

#include<cstring>
#include
<cstdio>
#include
<iostream>
using namespace std;

int a[30][30];
bool no[30][30];
bool ok;
int N,L;
void Init()
{
    scanf(
"%d%d",&L,&N);
    memset(a,
0,sizeof(a));
    
int x,y;
    
for (int i=1;i<=N;i++)
    {
        scanf(
"%d%d",&x,&y);
        a[x][y]
=1;
    }
    
for (int i=1;i<=L;i++)
        
for (int j=1;j<=L;j++)
            a[i][j]
+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
}
void dfs(int x,int y)
{
    
if (ok) return ;
    
if (x>L)
    {
        ok
=truereturn ;
    }
    
int o,k,m; bool check;
    
if (no[x][y])
    {
        
if (y>=L) dfs(x+1,1);
        
else dfs(x,y+1);
    }
    
else
    {
        check
=true;
        o
=L-x+1;
        
if (L-y+1<o) o=L-y+1;
        
for (int p=1;p<=o;p++)
        {
            
if (no[x][y+p-1])
            {
                check
=false; k=p;
                
break;
            }
            m
=a[x+p-1][y+p-1]-a[x+p-1][y-1]-a[x-1][y+p-1]+a[x-1][y-1];
            
if (m>1)
            {
                check
=false; k=p;
                
break;
            }
            
else
            {
                
for (int i=x;i<=x+p-1;i++)
                    no[i][y
+p-1]=true;
                
for (int i=y;i<=y+p-2;i++)
                    no[x
+p-1][i]=true;
                
if (m==1)
                {
                    
if (y+p>L) dfs(x+1,1);
                    
else dfs(x,y+p);
                }
                
if (ok) return ;
            }
        }
        
if (!check) k--;
        
else k=o;
        
for (int i=x;i<=x+k-1;i++)
            
for (int j=y;j<=y+k-1;j++)
                no[i][j]
=false;
    }
}
int main()
{
    
int test;
    scanf(
"%d",&test);
    
while (test)
    {
        Init();
        memset(no,
false,sizeof(no));
        ok
=false;
        dfs(
1,1);
        
if (!ok) printf("No\n");
        
else printf("Yes\n");
        test
--;
    }
    
return 0;
}
posted on 2009-09-12 20:59 开拓者 阅读(201) 评论(0)  编辑 收藏 引用 所属分类: 算法&例题Vijos OJ

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