zoukankan      html  css  js  c++  java
  • 【BZOJ】2719 银河之星

    可以将棋子分为9种类型。且可以通过合并使得两个不同种类棋子转换为另一种棋子(不过要注意棋盘大小,有的时候硬要合并会到棋盘外面,可以先把棋盘全部转换,然后枚举每一个棋子的转换)。然后把状态压成一个十位的十进制数就可以记忆化搜索了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 #define id(i,j) ((i-1)*3+j-1);
     5 struct point{
     6     int a,b;
     7 }p[15];
     8 int k,n,m,x,y,g[105][105],tot[15],change[10][10];
     9 const int dir[8][2]={0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1};
    10 LL bg,fin,bin[15];
    11 bool flag;
    12 map<LL,int>lis;
    13 bool dfs(LL st){
    14     if(lis[st]){
    15         if(lis[st]==1) return true;
    16         return false;
    17     }
    18     if(st==fin) return true;
    19     LL tmp;
    20     for(int i=0;i<9;i++)
    21         if((st%bin[i+1])/bin[i]>0){
    22              for(int j=0;j<9;j++)
    23              if(change[i][j]!=-1 && (st%bin[j+1])/bin[j]>0){
    24              tmp=st,tmp=tmp-(bin[i]+bin[j])+bin[change[i][j]];
    25              if(dfs(tmp)) {lis[tmp]=1; return true;}
    26              }
    27         }
    28     lis[st]=2;
    29     return false;
    30 }
    31 int main(){
    32     bin[0]=1;
    33     for(int i=1;i<=10;i++) bin[i]=bin[i-1]*10;
    34     while(scanf("%d%d%d%d%d",&k,&n,&m,&x,&y)!=EOF){
    35         lis.clear(); bg=0; flag=0;
    36         int num=id(((x-1)%3+1),((y-1)%3+1));
    37         fin=bin[num];
    38         memset(tot,0,sizeof(tot));
    39         memset(change,-1,sizeof(change));
    40         for(int a,b,i=1;i<=k;i++) {
    41             scanf("%d%d",&a,&b);
    42             p[i]=(point){a,b};
    43             int num=id(((a-1)%3+1),((b-1)%3+1));
    44             tot[num]++;
    45             if(tot[num]==10) puts("No"),flag=1;
    46             else bg+=bin[num];
    47         }
    48         if(flag) continue;
    49         for(int i=0;i<n;i++)
    50           for(int j=0;j<m;j++)
    51             g[i+1][j+1]=id((i%3+1),(j%3+1));
    52         for(int i=1;i<=n;i++)
    53           for(int j=1;j<=m;j++)
    54             for(int d=0;d<8;d++){
    55               int ta=i+2*dir[d][0],tb=j+2*dir[d][1];
    56               if(ta<1 || ta>n || tb<1 || tb>m) continue;
    57             change[g[ta-dir[d][0]][tb-dir[d][1]]][g[i][j]]=change[g[i][j]][g[ta-dir[d][0]][tb-dir[d][1]]]=g[ta][tb];
    58           }
    59         if(dfs(bg)) puts("Yes");
    60         else puts("No");
    61     }
    62     return 0;
    63 }
  • 相关阅读:
    一条长为L的绳子,一面靠墙,另外三边组成矩形,问此矩形最大面积能是多少?
    幸运的背后,总是靠自身的努力在支撑
    ZT:没有谁的成功是横空出世
    Node.js abaike图片批量下载爬虫1.02
    Node.js nvshens图片批量下载爬虫1.01
    Node.js meitulu图片批量下载爬虫1.051
    JDBC学习再小结
    JDBC学习小结
    day06_JDBC学习笔记
    MySQL学习小结
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/6071375.html
Copyright © 2011-2022 走看看