我爱崔老师系列之 新学的位运算枚举~ HDU4462 scaring the birds 杭州现场赛J题,枚举。

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4462

当时比赛的时候读错题意了。。。很悲催的没有考虑n*n个稻草人的时候。。。。然后一直WA= =。。。悲剧啊。。。。

回来的时候崔老师教了一个枚举的办法。。。就是位运算。。之前做的一道DFS也可以用位运算来写(其实取1或者取0的dfs都可以用位运算写= =)~、

膜拜崔老师~

View Code
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int map[55][55];
int hash[55][55],count,n;
using namespace std;
struct node
{
    int x,y,r;
}scare[15];
int top,q[100],ans,leap;
int judge()
{
    int i,j;
    for(i = 1;i <= n;i++)
    {
        for(j = 1;j <= n;j++)
        {
            if(!hash[i][j]&&map[i][j] == 0)
            return 0;
        }
    }
    return 1;
}
void reverse(int t)
{
    int i,j,x1,x2,y1,y2;
    x1 = scare[t].x-scare[t].r;
    x2 = scare[t].x+scare[t].r;
    y1 = scare[t].y-scare[t].r;
    y2 = scare[t].y+scare[t].r;
    if(x1 < 1)//防止数组越界
    x1 = 1;
    if(y1 < 1)
    y1 = 1;
    if(x2 > n)
    x2 = n;
    if(y2 > n)
    y2 = n;
    for(i = x1;i <= x2;i++)//在那个方格中找
    {
        for(j = y1;j <= y2;j++)
        {
            if(abs(i-scare[t].x)+abs(j-scare[t].y) <= scare[t].r && hash[i][j] != 1)
            map[i][j] = 1;
        }
    }
}
void recover(int t)
{
    int i,j,x1,x2,y1,y2;
    x1 = scare[t].x-scare[t].r;
    x2 = scare[t].x+scare[t].r;
    y1 = scare[t].y-scare[t].r;
    y2 = scare[t].y+scare[t].r;
    if(x1 < 1)//防止数组越界
    x1 = 1;
    if(y1 < 1)
    y1 = 1;
    if(x2 > n)
    x2 = n;
    if(y2 > n)
    y2 = n;
    for(i = x1;i <= x2;i++)
    {
        for(j = y1;j <= y2;j++)
        {
            if(abs(i-scare[t].x)+abs(j-scare[t].y) <= scare[t].r && hash[i][j] != 1)
            map[i][j] = 0;
        }
    }
}
int main()
{
    int m,i,j;
    while(scanf("%d",&n)&&n)
    {
        leap = 0;
        memset(map,0,sizeof(map));
        memset(hash,0,sizeof(hash));
        cin>>m;
        ans = 1000;
        for(i = 0;i < m;i++)
        {
            scanf("%d %d",&scare[i].x,&scare[i].y);
            hash[scare[i].x][scare[i].y] = 1;//把稻草人的地方标记一下,省的找了。。。稻草人本来就是空地不用考虑上不上色、
        }
        for(i = 0;i < m;i++)
        {
            cin>>scare[i].r;
        }

        if(n*n == m)
        {
            cout<<"0"<<endl;
            continue;
        }

        for(i = 0;i < (1<<m);i++)
        {
            count = top = 0;
            for(j = 0;j < m;j++)
            {
                if((1<<j)&i)//第J个在i情况中用到。
                {

                    count++;
                    reverse(j);
                    q[top++] = j;
                }
            }

            if(judge())
            {
                if(ans > count)
                ans = count;
                leap = 1;
            }
            while(top > -1)
            {
                recover(q[--top]);
            }
        }
        if(leap)
        cout<<ans<<endl;
        else
        puts("-1");


    }
    return 0;
}

  1 #include<stdio.h>
  2 #include<string.h>
  3 char map[205][205];
  4 struct node
  5 {
  6     int x,y,step,f;//f存先驱,step是当前的步数。
  7 }q[400005];
  8 
  9 int way[400005];//用来最后存路径
 10 int f,r,m,n,fa,leap;
 11 int vis[205][205];
 12 int to[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};//四个方向
 13 void sort()//优先队列排序
 14 {
 15     int i;
 16     struct node t;
 17     for(i = r;i > f;i--)
 18     {
 19         if(q[i].step < q[i-1].step)
 20         {
 21             t = q[i];
 22             q[i] =q[i-1];
 23             q[i-1] = t;
 24         }
 25         else
 26         break;
 27     }
 28 }
 29 void bfs()
 30 {
 31     int i,j,nx,ny;
 32     memset(vis,0,sizeof(vis));
 33     f = r = 0;
 34     leap = 0;
 35     q[r].x = 0;
 36     q[r].y = 0;
 37     if(map[0][0] == 'X')//看看开头能不能走
 38     leap = 0;
 39     else
 40     {
 41 
 42     if(map[0][0] != '.'&& map[0][0] != 'X')//如果是数字的话开头是不能直接将STEP = 0 的。
 43     q[r].step = map[0][0]-'0';
 44     else
 45     q[r].step = 0;
 46     q[r].f = -1;
 47     vis[0][0] = 1;
 48     r++;
 49     while(f < r)
 50     {
 51         struct node now;
 52         fa = f;
 53         now = q[f++];
 54         for(i = 0;i < 4;i++)
 55         {
 56             nx = now.x+to[i][0];
 57             ny = now.y+to[i][1];
 58 
 59             if(nx >= 0 && nx < m && ny >= 0 && ny < n && map[nx][ny] != 'X' && !vis[nx][ny])
 60             {
 61                 q[r].x = nx;
 62                 q[r].y = ny;
 63 
 64                 q[r].f = fa;
 65                 if(map[nx][ny] == '.')
 66                 q[r].step = now.step+1;
 67                 else
 68                 q[r].step = map[nx][ny]-'0'+now.step + 1;
 69 
 70                 if(nx == m-1 && ny == n-1)
 71                 {
 72                     leap = 1;
 73                     break;
 74                 }
 75                  sort();//优先队列排序。。。这里一定不要加错位置、
 76                 r++;
 77                 vis[nx][ny] = 1;
 78             }
 79         }
 80         if(leap)
 81         break;
 82     }
 83     }
 84 }
 85 int main()
 86 {
 87 
 88 
 89      
 90     int i,count,j,nt;
 91     while(~scanf("%d %d",&m,&n))
 92     {
 93         if(!(m||n))
 94         break;
 95         memset(map,0,sizeof(map));
 96         for(i = 0;i < m;i++)
 97         scanf("%s",map[i]);
 98         bfs();
 99         if(leap)
100         {
101             printf("It takes %d seconds to reach the target position, let me show you the way.\n",q[r].step);
102             count = -1;
103             while(1)
104             {
105                 way[++count] = r;
106                 r = q[r].f;
107                 if(r == -1)
108                 break;
109             }
110             nt = 1;
111             for(i = count;i > 0;i--)
112             {
113                 printf("%ds:(%d,%d)->(%d,%d)\n",nt++,q[way[i]].x,q[way[i]].y,q[way[i-1]].x,q[way[i-1]].y);
114                 if(map[q[way[i-1]].x][q[way[i-1]].y] != '.' )
115                 {
116                     int time;
117                     time = map[q[way[i-1]].x][q[way[i-1]].y]-'0';
118                     for(j = 0;j < time;j++)
119                     {
120                         printf("%ds:FIGHT AT (%d,%d)\n",nt++,q[way[i-1]].x,q[way[i-1]].y);
121                     }
122                 }
123             }
124 
125         }
126         else
127         puts("God please help our poor hero.");
128         puts("FINISH");
129     }
130     return 0;
131 }
原文地址:https://www.cnblogs.com/0803yijia/p/2763989.html