zoukankan      html  css  js  c++  java
  • HDU 4536 XCOM Enemy Unknown ( 状态压缩+搜索)

    XCOM Enemy Unknown

    Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 133    Accepted Submission(s): 34


    Problem Description
    XCOM-Enemy Unknown是一款很好玩很经典的策略游戏.
    在游戏中,由于未知的敌人--外星人入侵,你团结了世界各大国家进行抵抗.


    随着游戏进展,会有很多的外星人进攻事件.每次进攻外星人会选择3个国家攻击,作为联盟的指挥者,你要安排有限的联盟军去支援其中一个国家,抵抗进攻这个国家的外星人.



    战斗胜利之后这个被支援的国家恐慌值就会-2点(恐慌值最少减为1),而其他两个未被支援的国家恐慌值就会+2点,同时和这两个国家在相同大洲的其他国家恐慌值也会+1点.
    当一个国家的恐慌值超过5点,这个国家就会对联盟失去信心从而退出联盟.
    现在给你外星人将会进攻的地点,问你最多能在不失去任何一个国家信任的情况下抵挡多少次外星人的进攻.
     
    Input
    第一行有一个整数T代表接下来有T组数据
    每组数据第一行是三个整数,n,m,k分别代表联盟国家的个数,大洲的个数,外星人的进攻次数.
    第二行是n个数字代表各个国家所属的大洲(大洲序号从0到m-1)
    第三行是n个数字代表各个国家初始的恐慌值
    接下去k行代表外星人进攻
    每行有三个数字,表示该次外星人进攻的国家(国家序号从0到n-1)

    [Technical Specification]
    0<T<=100
    8<n<=16
    2<m<=5
    0<k<=100
    0<初始恐慌值<=5
    每个州至少有三个国家
    每次外星人进攻一定发生在不同州的三个国家
     
    Output
    首先输出case数(见sample),接着输出在不失去任何一个国家的情况下能抵挡外星人进攻最多的次数.
     
    Sample Input
    1 9 3 2 0 0 0 1 1 1 2 2 2 3 3 3 3 3 3 3 3 3 0 3 6 0 3 6
     
    Sample Output
    Case #1: 1
    Hint
    第一次如果选择了0,那么3和6的恐慌值就会增加到5,第二次不管怎么选择,3和6总会有一个超过5.
     
    Source
     
    Recommend
    liuyiding

    直接搜索的。

    用二进制进行压缩,3为二进制表示一个。用long long

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <map>
    #include <string>
    #include <set>
    #include <queue>
    #include <math.h>
    using namespace std;
    
    int a[20];
    int b[20];
    
    int x[100],y[100],z[100];
    int ans;
    int n,m,k;
    
    long long change1(int t[])
    {
        long long temp=0;
        for(int i=0;i<n;i++)
        {
            temp<<=3;
            temp|=t[i];
        }
        return temp;
    }
    void change2(int t[],long long p)
    {
        for(int i=n-1;i>=0;i--)
        {
            t[i]=p&7;
            p>>=3;
        }
    }
    
    void dfs(long long state,int t)
    {
        ans=max(ans,t);
        if(t>=k)return;
        long long temp;
        bool flag;
    
        change2(a,state);
        a[x[t]]-=2;
        if(a[x[t]]<1)a[x[t]]=1;
    
        a[y[t]]+=1;
        a[z[t]]+=1;
        for(int i=0;i<n;i++)
          if(i!=x[t] && (b[y[t]]==b[i]||b[z[t]]==b[i]))
            a[i]++;
        flag=true;
        for(int i=0;i<n;i++)
          if(a[i]>5)
          {
              flag=false;
              break;
          }
        if(flag)
        {
            long long temp=change1(a);
            dfs(temp,t+1);
        }
    
        change2(a,state);
        a[y[t]]-=2;
        if(a[y[t]]<1)a[y[t]]=1;
    
        a[x[t]]+=1;
        a[z[t]]+=1;
        for(int i=0;i<n;i++)
          if(i!=y[t] && (b[x[t]]==b[i]||b[z[t]]==b[i]))
            a[i]++;
        flag=true;
        for(int i=0;i<n;i++)
          if(a[i]>5)
          {
              flag=false;
              break;
          }
        if(flag)
        {
            long long temp=change1(a);
            dfs(temp,t+1);
        }
    
        change2(a,state);
        a[z[t]]-=2;
        if(a[z[t]]<1)a[z[t]]=1;
    
        a[y[t]]+=1;
        a[x[t]]+=1;
        for(int i=0;i<n;i++)
          if(i!=z[t] && (b[y[t]]==b[i]||b[x[t]]==b[i]))
            a[i]++;
        flag=true;
        for(int i=0;i<n;i++)
          if(a[i]>5)
          {
              flag=false;
              break;
          }
        if(flag)
        {
            long long temp=change1(a);
            dfs(temp,t+1);
        }
    
    
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        int iCase=0;
        while(T--)
        {
            iCase++;
            scanf("%d%d%d",&n,&m,&k);
            for(int i=0;i<n;i++)
              scanf("%d",&b[i]);
            for(int i=0;i<n;i++)
              scanf("%d",&a[i]);
            for(int i=0;i<k;i++)
              scanf("%d%d%d",&x[i],&y[i],&z[i]);
            ans=0;
    
            long long tmp=change1(a);
    
            dfs(tmp,0);
    
            printf("Case #%d: %d\n",iCase,ans);
        }
        return 0;
    }
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    《Effective C++》第8章 定制new和delete-读书笔记
    《TCP/IP详解卷1:协议》第3章 IP:网际协议(2)-读书笔记
    【剑指Offer】14合并两个排序的链表
    【剑指Offer】13反转链表
    【剑指Offer】12链表中倒数第k个结点
    【剑指Offer】11调整数组顺序使奇数位于偶数前面
    【剑指Offer】10数值的整数次方
    【剑指Offer】09二进制中1的个数
    【剑指Offer】08矩形覆盖
    【剑指Offer】07变态跳台阶
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2991053.html
Copyright © 2011-2022 走看看