zoukankan      html  css  js  c++  java
  • hdu4499 搜索

    题意:
          给你一个棋盘,最大是5*5的,问你最多可以放多少个炮,炮和炮之间不可以相互攻击,这块只的是只能走一步,不存在两个炮中间三个棋子的情况..

    思路:

       刚开始想的是把所有的空位置都放上炮,然后最大点权独立集,结果没有办法把这个图弄成二分图,没招了,直接搜索吧,把每一个点分成两种情况,如果之前就有棋子,那么无话说直接下进入下一层,如果没有棋子,我们有两种选择,放炮和不放炮,先把不放炮写上,然后判断下是否可以放,我的想法是当前的位置只会影响当前位置的这一行和这一列,直接判断吧当前位置放上炮后的这行和这列是否满足条件,判断方法是枚举任意三个连续(不一定相邻)的数组,看第一个和第二个是否都是炮,至于怎么枚举画下就知道了,其实可以优化的,我们是从左往右,从上往下的,所以可以直接判断上和左就行了,自己懒得优化了,5*5不大怎么写都行..



    #include<stdio.h>
    #include<string.h>
    
    int num[6][6];
    int mark[6][6];
    int xx ,yy ,ans;
    
    
    bool OK(int xxx ,int yyy)
    {
       int mk = 0;
       int s ,s1 ,s2 ,s3;
       for(int iii = 0 ;iii < 3 ;iii ++)
       {
            s = 0;
            for(int ii = iii ;ii < yy ;ii ++)
            {
                if(!num[xxx][ii]) continue;
                s++;
                if(s == 1) s1 = num[xxx][ii];
                if(s == 2) s2 = num[xxx][ii];
                if(s == 3) s3 = num[xxx][ii];
                if(s == 3) break;
             }
             if(s == 3 && s1== 2 && s3 == 2)
             {
                mk = 1;
                break;
             }
          }
          if(!mk)
          for(int iii = 0 ;iii < 3 ;iii ++)
          {
             s = 0;
             for(int ii = iii ;ii < xx ;ii ++)
             {
                if(!num[ii][yyy]) continue;
                s++;
                if(s == 1) s1 = num[ii][yyy];
                if(s == 2) s2 = num[ii][yyy];
                if(s == 3) s3 = num[ii][yyy];
                if(s == 3) break;
             }
                
             if(s == 3 && s1== 2 && s3 == 2)
             {
                mk = 1;
                break;
             }
         }
         return mk == 0;
    }
    
    void DFS(int sum ,int nowx ,int nowy)
    {
       if(ans < sum) ans = sum;
       int x = nowx ,y = nowy + 1;
       if(y == yy)
       {
          x++ ,y = 0;
       }
       if(mark[x][y] || x == xx) return;  
       if(num[x][y]) 
       {  
          mark[x][y] = 1;
          DFS(sum ,x ,y);
          mark[x][y] = 0;
       }
       else
       {
          mark[x][y] = 1;
          DFS(sum ,x ,y);
          mark[x][y] = 0;
          num[x][y] = 2;
          if(OK(x ,y))
          {
             mark[x][y] = 1;
             DFS(sum + 1 ,x ,y);
             mark[x][y] = 0;      
          } 
          num[x][y] =  0;
       }
       return ;
    }
       
        
    int main ()
    {
       int i ,q;
       int x ,y;
       while(~scanf("%d %d %d" ,&xx ,&yy ,&q))
       {
          memset(num ,0 ,sizeof(num));
          for(i = 1 ;i <= q ;i ++)
          {
             scanf("%d %d" ,&x ,&y);
             num[x][y] = 1;
          }
          ans = 0;
          memset(mark ,0 ,sizeof(mark));
          DFS(0 ,0 ,-1);
          printf("%d
    " ,ans);    
          
       }
       return 0;
    }
    

  • 相关阅读:
    atitit.session的原理以及设计 java php实现的异同
    atitit.破解 拦截 绕过 网站 手机 短信 验证码 之自动获取手机短信方式 attilax 总结
    java softReference 详解
    android开发:TextView中android:autoLink属性的作用
    抽象类和接口的简单差别
    android一个简单的线程实例
    Java 批注
    最简单的菜单操作
    AsyncTask的参数介绍
    (转)android中ListView在划屏到底部的时候动态添加ListView的Item实现
  • 原文地址:https://www.cnblogs.com/csnd/p/12063216.html
Copyright © 2011-2022 走看看