• [hdu1401] Solitaire


    hdu 1401 传送门

    poj 1198 传送门

    uva 1724 传送门

    折半搜索就好了。

    用个map记忆一下。

    记录旗子的位置再排序也能做。

    但是考虑到8*8正好能用long long压一下,所以我是状压了棋盘。

    注意如果用dfs不要判重,有可能状态一样,但是步数不同。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<map>
     5 using namespace std;
     6 typedef unsigned long long ull;
     7 const ull u=1ull;
     8 
     9 int ans;
    10 ull st,ed;
    11 map<ull,int>mp;
    12 
    13 int dfs(ull s,int kd,int r)
    14 {
    15     if(mp[s]==3-kd)return 1;
    16     mp[s]=kd;
    17     if(!r)return 0;
    18     r--;
    19     int ret=0;
    20     for(int i=0;i<64;i++)
    21     {
    22         if(!(s&(u<<i)))continue;
    23         ull to=s^(u<<i);
    24         if(i%8<7&&(!(s&(u<<i+1))))
    25             ret|=dfs(to|(u<<i+1),kd,r);
    26         if(i%8<6&&(s&(u<<i+1))&&(!(s&(u<<i+2))))
    27             ret|=dfs(to|(u<<i+2),kd,r);
    28         if(i%8>0&&(!(s&(u<<i-1))))
    29             ret|=dfs(to|(u<<i-1),kd,r);
    30         if(i%8>1&&(s&(u<<i-1))&&(!(s&(u<<i-2))))
    31             ret|=dfs(to|(u<<i-2),kd,r);
    32         if(i>=8&&(!(s&(u<<i-8))))
    33             ret|=dfs(to|(u<<i-8),kd,r);
    34         if(i>=16&&(s&(u<<i-8))&&(!(s&(u<<i-16))))
    35             ret|=dfs(to|(u<<i-16),kd,r);
    36         if(i+8<64&&(!(s&(u<<i+8))))
    37             ret|=dfs(to|(u<<i+8),kd,r);
    38         if(i+16<64&&(s&(u<<i+8))&&(!(s&(u<<i+16))))
    39             ret|=dfs(to|(u<<i+16),kd,r);
    40     }
    41     return ret;
    42 }
    43 
    44 int main()
    45 {
    46     int pos[4][2];
    47     while(scanf("%d%d",&pos[0][0],&pos[0][1])!=EOF)
    48     {
    49         mp.clear();
    50         ans=st=ed=0;
    51         for(int i=1;i<4;i++)
    52             scanf("%d%d",&pos[i][0],&pos[i][1]);
    53         for(int i=0;i<4;i++)
    54             for(int j=0;j<2;j++)pos[i][j]--;
    55         for(int i=0;i<4;i++)
    56             st|=(u<<((pos[i][0]<<3)+pos[i][1]));
    57         for(int i=0;i<4;i++)
    58             scanf("%d%d",&pos[i][0],&pos[i][1]);
    59         for(int i=0;i<4;i++)
    60             for(int j=0;j<2;j++)pos[i][j]--;
    61         for(int i=0;i<4;i++)
    62             ed|=(u<<((pos[i][0]<<3)+pos[i][1]));
    63         dfs(st,1,4);
    64         ans=dfs(ed,2,4);
    65         printf(ans?"YES
    ":"NO
    ");
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    Oracle 查询表空间容量脚本
    C#保留小数位的方法集合
    asp.net c# 去掉字符串中重复项并将结果遍历出来算法
    汇总sql server数据库所有表名、列数、行数
    Web表单设计之注册表单
    精简高效的CSS命名准则和方法
    MSSQL查看和解除表锁
    XML通用操作类
    Ajax学习笔记一(xmlHttpRequest对象)
    SQL Server无法生成FRunCM线程|FRunCM 线程|FRunCM
  • 原文地址:https://www.cnblogs.com/cervusy/p/10003504.html
Copyright © 2020-2023  润新知