您的位置:首页 > 其它

HDU 4536 XCOM Enemy Unknown ( 状态压缩+搜索)

2013-03-30 22:32 344 查看

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


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



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



战斗胜利之后这个被支援的国家恐慌值就会-2点(恐慌值最少减为1),而其他两个未被支援的国家恐慌值就会+2点,同时和这两个国家在相同大洲的其他国家恐慌值也会+1点.
当一个国家的恐慌值超过5点,这个国家就会对联盟失去信心从而退出联盟.
现在给你外星人将会进攻的地点,问你最多能在不失去任何一个国家信任的情况下抵挡多少次外星人的进攻.

[align=left]Input[/align]
第一行有一个整数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
每个州至少有三个国家
每次外星人进攻一定发生在不同州的三个国家

[align=left]Output[/align]
首先输出case数(见sample),接着输出在不失去任何一个国家的情况下能抵挡外星人进攻最多的次数.

[align=left]Sample Input[/align]

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

[align=left]Sample Output[/align]

Case #1: 1

Hint

第一次如果选择了0,那么3和6的恐慌值就会增加到5,第二次不管怎么选择,3和6总会有一个超过5.

[align=left]Source[/align]
2013腾讯编程马拉松复赛第二场(3月30日)

[align=left]Recommend[/align]
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: