zoukankan      html  css  js  c++  java
  • 【noip2011】Mayan游戏

    题解:

    刷了一天的noip啊 做了10题! 突然找回了做马拉松的感觉- -

    我中午竟然放弃治疗去看视频 做到晚上累得都快挂了 用电脑放一些rock 把音乐当咖啡硬撑下来 但是还是没能刷3届

    唉 显然速度刷题是很容易忘的 简单写一些题解 然后睡觉去(- -。zZ)

    赤裸裸的搜索 但是要加一些剪枝

    1.如果交换的两个方块颜色相同则不换

    2.如果移动时是向左且左边有方块则不动(左边的往右效果一样)

    3.如果任意颜色发方块个数为1或2 显然无解return

    我只加了这些剪枝速度貌似还不错 vijos上1300ms左右

    关键是很多人说这题很复杂 - -?

    其实思路清楚就不会(表示半小时搞定) 我感觉做这题就像在做游戏一样

    可以写两个函数fall 和clean做掉落和清除 然后在要调用的地方写函数就会觉得清晰多了

    代码:

     1 #include <cstdio>
     2 #include <cstdlib>
     3 struct info{
     4     int a[7][9];
     5     void print(){
     6         for (int i=7;i>=1;i--){
     7             for (int j=1;j<=5;j++) printf("%d ",a[j][i]);
     8             puts("");
     9         }
    10         puts("");
    11     }
    12 }now,save[6];
    13 int n,rem[11],srem[6][11],ans[6][3],bo[7][9];
    14 void swap(int &a,int &b){ int x=a; a=b,b=x; }
    15 void fall(){
    16     for (int i=1;i<=5;i++)
    17     for (int j=2;j<=7;j++)
    18     if (!now.a[i][j-1] && now.a[i][j]){
    19         int k;
    20         for (k=j-1;!now.a[i][k] && k>=1;--k);
    21         ++k;
    22         swap(now.a[i][j],now.a[i][k]);
    23     }
    24 }
    25 void markbo(){
    26     for (int i=1;i<=5;i++)
    27     for (int j=1;j<=8;j++)
    28     if (now.a[i][j]){
    29         if (now.a[i-1][j]==now.a[i][j] && now.a[i+1][j]==now.a[i][j]){
    30             bo[i-1][j]=1;
    31             bo[i][j]=1;
    32             bo[i+1][j]=1;
    33         }
    34         if (now.a[i][j-1]==now.a[i][j] && now.a[i][j+1]==now.a[i][j]){
    35             bo[i][j-1]=1;
    36             bo[i][j]=1;
    37             bo[i][j+1]=1;
    38         }
    39     }
    40 }
    41 bool clean(){
    42     markbo();
    43     int res=0;
    44     for (int i=1;i<=5;i++)
    45     for (int j=1;now.a[i][j] && j<=8;j++)
    46     if (bo[i][j]){
    47         res=1;
    48         bo[i][j]=0;
    49         --rem[now.a[i][j]];
    50         now.a[i][j]=0;
    51     }
    52     return res;
    53 }
    54 int work(int x,int y,int z){
    55     swap(now.a[x][y],now.a[x+z][y]);
    56     fall();
    57     while (clean()) fall();
    58     int res=0;
    59     for (int i=1;i<=10;i++)
    60     if (rem[i])
    61     if (!res || res>rem[i]) res=rem[i];
    62     return res;
    63 }
    64 void print(){
    65     for (int i=1;i<=n;i++)
    66     printf("%d %d %d
    ",ans[i][0]-1,ans[i][1]-1,ans[i][2]);
    67     exit(0);
    68 }
    69 void search(int t){
    70     //printf("%d:
    ",t);
    71     //now.print();
    72     save[t]=now;
    73     for (int i=1;i<=10;i++) srem[t][i]=rem[i];
    74     for (int i=1;i<=5;i++)
    75     for (int j=1;now.a[i][j] && j<=7;j++)
    76     for (int k=1;k>=-1;k-=2)
    77     if (i+k>0 && i+k<=5){
    78         if ((k==-1 && now.a[i-1][j]) || now.a[i][j]==now.a[i+k][j]) continue;
    79         ans[t][0]=i,ans[t][1]=j,ans[t][2]=k;
    80         int x=work(i,j,k);
    81         if (t==n){
    82             if (x==0) print();
    83         }else if (x>2) search(t+1);
    84         now=save[t];
    85         for (int l=1;l<=10;l++) rem[l]=srem[t][l];
    86     }
    87 }
    88 int main(){
    89     scanf("%d",&n);
    90     for (int x,i=1;i<=5;i++)
    91     while (scanf("%d",&x),x){
    92         now.a[i][++now.a[i][0]]=x;
    93         ++rem[x];
    94     }
    95     for (int i=1;i<=5;i++) now.a[i][0]=0;
    96     search(1);
    97     puts("-1");
    98 }
    View Code
  • 相关阅读:
    parted 2T以上磁盘分区和挂载
    MySQL 表空间恢复
    MySQL 绿色版安装
    EF core
    让vs自动提示没有using的类
    Android Studio 的 Gradle 面板没有 Task
    JMS微服务远程调用性能测试 vs .Net Core gRPC服务
    electron打包,使用electron-packager
    EasyNetQ(RabbitMQ)在处理消息时,如果抛出异常,继续不断发送到订阅队列,不断处理(也就是不自动确认消息已到达)
    调用系统默认浏览器,打开网页
  • 原文地址:https://www.cnblogs.com/g-word/p/3383379.html
Copyright © 2011-2022 走看看