题目描述
Jimmy 热衷于一个叫 undercards 的游戏。
在 undercards 中,有四个格子。每个格子要么是空的,要么住着一只 BigBob。每个 BigBob 有一个不超过 k 的血量;血量减到 0 视为死亡,它所在的那个格子随即空出。
当一只 BigBob 受到伤害后,假如它没有死亡且剩余血量为 t,它会立刻从左数第一个空格处召唤一只血量为 a[t]的 BigBob;召唤新 BigBob 时若没有空格,则不会召唤。
法术 R 定义为:从左往右,依次对每个 BigBob 造成一点伤害,且每对一只 BigBob 造成伤害后,会立刻进行死亡判定、或立刻召唤一只新的 BigBob。发动完一次法术 R 后,如果过程中有 BigBob 死亡,则会再发动一次法术 R,否则不再发动。
聪明的 Jimmy 发现,在某些情况下,当他发动法术 R 时,游戏会陷入循环。他想求出这样的初始情形有多少种。
输入
从文件 bob.in
中读入数据。
输入一个正整数 k;
随后一行 k-1 个正整数,表示 a[1]~a[k-1];
输出
输出到文件 bob.out
中。
输出一个整数,表示答案。
样例数据
输入 #1 复制
2 2
输出 #1 复制
31
数据范围限制
对于 30% 的数据,k≤5;
对于 70% 的数据,k≤10, a[i]=k;
对于 100% 的数据,k≤15, 1≤a[i]≤k。
提示
以样例为例:
当初始 4 个空格分别为 (0,0,2,0) 时,法术 R 发动过程中只有第三格的 BigBob 受到一点伤害,并在第一格放置一个血量为 2 的 BigBob,法术完成后 4 个空格为 (2,0,1,0)。且由于过程中没有 BigBob 死亡,法术不再发动;
当初始 4 个空格分别为 (2,0,1,0) 时,法术 R 发动过程如下:
- 第一格的 BigBob 受到一点伤害,在第二格放置一个血量为 2 的 BigBob;
- 第二格的 BigBob 受到一点伤害,在第四格放置一个血量为 2 的 BigBob;
- 第三格的 BigBob 受到一点伤害,并死亡;
- 第四格的 BigBob 受到一点伤害,在第三格放置一个血量为 2 的 BigBob。
法术完成后 4 个空格为 (1,1,2,1),由于过程中有 BigBob 死亡,因此会继续发动法术。
【样例解释】
BigBob 最多有 2 血,满血 BigBob 受伤会召出新的。
导致游戏进入循环的初始状态有:
(2,1,0,0),(1,2,0,0),(2,0,1,0),(2,1,1,0),(0,2,1,0),(1,2,1,0),(2,2,1,0) ,(1,0,2,0),(0,1,2,0),(1,1,2,0),(2,1,2,0),(2,1,0,1),(0,2,0,1),(1,2,0,1),(0,2,1,1),(1,2,1,1),(0,0,2,1),(1,0,2,1),(0,1,2,1),(1,1,2,1),(2,1,2,1),(0,2,2,1),(1,2,2,1),(2,1,0,2) ,(1,2,0,2),(2,0,1,2),(2,1,1,2),(0,2,1,2),(1,2,1,2),(2,2,1,2),(2,1,2,2)共 31 种。
这道题就是纯模拟,像一个举例出每一种可能,在判断是否成立,若成立,就ans++,最后输出ans就行了
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[20],f[25],ans;
bool c,visit[25][25][25][25];
bool bob(int x,int y,int xx,int yy)
{
f[1]=x,f[2]=y,f[3]=xx,f[4]=yy;
if(x==0&&y==0&&xx==0&&yy==0)
{
return 0;
}
memset(visit,0,sizeof(visit));
visit[x][y][xx][yy]=1;
while(1)
{
c=0;
for(int i=1;i<=4;i++)
{
if(f[i]!=0)
{
f[i]-=1;
if(f[i]!=0)
{
for(int j=1;j<=4;j++)
{
if(f[j]==0)
{
f[j]=a[f[i]];
break;
}
}
}
else
{
c=1;
}
}
}
if(c==0||f[1]+f[2]+f[3]+f[4]==0)
{
return 0;
}
if(visit[f[1]][f[2]][f[3]][f[4]]==1)
{
break;
}
else
{
visit[f[1]][f[2]][f[3]][f[4]]=1;
}
}
return 1;
}
int main()
{
freopen("bob.in","r",stdin);
freopen("bob.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
for(int k=0;k<=n;k++)
{
for(int i1=0;i1<=n;i1++)
{
if(bob(i,j,k,i1)==1)
{
ans+=1;
}
}
}
}
}
printf("%d",ans);
return 0;
}