poj2044

只要记录4个顶点的不下雨天数还是很妙的

#include<stdio.h>
#include<string.h>


int DAY[367];
bool mark[366][10][8][8][8][8];
int ys[12] = {0 ,1 ,2 ,3 ,0 ,4 ,5 ,6 ,0 ,7 ,8 ,9};
int dir[9][2] = {0 ,0 ,0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0 ,0 ,2 ,0 ,-2 ,2 ,0 ,-2 ,0};
int OK ,T;


bool ok(int t ,int x ,int y ,int a[])
{


    int aa = (x - 1) * 4 + y;
    int bb= (x - 1 + 1) * 4 + y;
    int cc = (x - 1) * 4 + y + 1;
    int dd = (x - 1 + 1) * 4 + y + 1;
    if(x < 1 || x > 3 || y < 1 || y > 3)
    return 0;
    if(a[1] >= 7 || a[2] >= 7 || a[3] >= 7 || a[4] >= 7)
    return 0;
    if(((1 << aa) & DAY[t]) || ((1 << bb) & DAY[t]) || ((1 << cc) & DAY[t]) || ((1 << dd) & DAY[t]))
    return 0;
    if(mark[t][ys[aa]][a[1]][a[2]][a[3]][a[4]]) return 0;
    return 1;


}


void DFS(int t ,int x ,int y ,int a[])
{
    if(t == T) OK = 1;
    if(OK) return ;
    int b[5];
    for(int i = 0 ;i < 9 ;i ++)
    {
        if(t == 0 && i) break;
        int nowt = t + 1;
        int nowx = x + dir[i][0];
        int nowy = y + dir[i][1];
        for(int j = 1 ;j <= 4 ;j ++)
        b[j] = a[j] + 1;
        if(nowx == 1 && nowy == 1) b[1] = 0;
        if(nowx == 1 && nowy == 3) b[2] = 0;
        if(nowx == 3 && nowy == 1) b[3] = 0;
        if(nowx == 3 && nowy == 3) b[4] = 0;
        if(ok(nowt ,nowx ,nowy ,b))
        {
            mark[nowt][ys[(nowx-1)*4+nowy]][b[1]][b[2]][b[3]][b[4]] = 1;
            DFS(nowt ,nowx ,nowy ,b);
        }
    }
    return ;
}


int main ()
{
    int i ,j;
    while(~scanf("%d" ,&T) && T)
    {
        memset(DAY ,0 ,sizeof(DAY));
        for(i = 1 ;i <= T ;i ++)
        {
            int tmp;
            for(j = 1 ;j <= 16 ;j ++)
            {
                scanf("%d" ,&tmp);
                DAY[i] = DAY[i] | (tmp << j);
            }
        }
        memset(mark ,0 ,sizeof(mark));
        OK = 0;
        int a[5];
        a[1] = a[2] = a[3] = a[4] = 0;
        DFS(0 ,2 ,2 ,a);
        printf("%d\n" ,OK);
    }
    return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值