恐怖的奴隶主(bob)

题目描述

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 发动过程如下:

  1. 第一格的 BigBob 受到一点伤害,在第二格放置一个血量为 2 的 BigBob;
  2. 第二格的 BigBob 受到一点伤害,在第四格放置一个血量为 2 的 BigBob;
  3. 第三格的 BigBob 受到一点伤害,并死亡;
  4. 第四格的 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值