L2-040 哲哲打游戏 (25 分)2021天梯赛c++

哲哲是一位硬核游戏玩家。最近一款名叫《达诺达诺》的新游戏刚刚上市,哲哲自然要快速攻略游戏,守护硬核游戏玩家的一切!

为简化模型,我们不妨假设游戏有 N 个剧情点,通过游戏里不同的操作或选择可以从某个剧情点去往另外一个剧情点。此外,游戏还设置了一些存档,在某个剧情点可以将玩家的游戏进度保存在一个档位上,读取存档后可以回到剧情点,重新进行操作或者选择,到达不同的剧情点。

为了追踪硬核游戏玩家哲哲的攻略进度,你打算写一个程序来完成这个工作。假设你已经知道了游戏的全部剧情点和流程,以及哲哲的游戏操作,请你输出哲哲的游戏进度。

输入格式:
输入第一行是两个正整数 N 和 M (1≤N,M≤10
​5),表示总共有 N 个剧情点,哲哲有 M 个游戏操作。接下来的 N 行,每行对应一个剧情点的发展设定。第 i 行的第一个数字是 K​i,表示剧情点 i 通过一些操作或选择能去往下面 K​i 个剧情点;接下来有 K​i个数字,第 k 个数字表示做第 k 个操作或选择可以去往的剧情点编号。
最后有 M 行,每行第一个数字是 0、1 或 2,分别表示:
0 表示哲哲做出了某个操作或选择,后面紧接着一个数字 j,表示哲哲在当前剧情点做出了第 j 个选择。我们保证哲哲的选择永远是合法的。
1 表示哲哲进行了一次存档,后面紧接着是一个数字 j,表示存档放在了第 j 个档位上。
2 表示哲哲进行了一次读取存档的操作,后面紧接着是一个数字 j,表示读取了放在第 j 个位置的存档。
约定:所有操作或选择以及剧情点编号都从 1 号开始。存档的档位不超过 100 个,编号也从 1 开始。游戏默认从 1 号剧情点开始。总的选项数(即 ∑K
​i
​​ )不超过 10
​6
​​ 。

输出格式:
对于每个 1(即存档)操作,在一行中输出存档的剧情点编号。

最后一行输出哲哲最后到达的剧情点编号。

输入样例:
10 11
3 2 3 4
1 6
3 4 7 5
1 3
1 9
2 3 5
3 1 8 5
1 9
2 8 10
0
1 1
0 3
0 1
1 2
0 2
0 2
2 2
0 3
0 1
1 1
0 2
输出样例:
1
3
9
10
样例解释:
简单给出样例中经过的剧情点顺序:

1 -> 4 -> 3 -> 7 -> 8 -> 3 -> 5 -> 9 -> 10。

档位 1 开始存的是 1 号剧情点;档位 2 存的是 3 号剧情点;档位 1 后来又存了 9 号剧情点.

第一版:

#include<bits/stdc++.h>
using namespace std;
int main(){
    
    
    ios::sync_with_stdio(false);
    //感觉好像就凭数组就可以解出,只要思路清晰就没问题
    int n1,n2,m1,t1,tmp,sign1,sign2;
    cin>>n1>>n2;
    int pp[n1][10]={
    
    0},stor[n1][3]={
    
    0};
    for(int i=1;i<=n1;i++)
    {
    
     cin>>m1;
     for(int j=1;j<=m1;j++)
         cin>>pp[i][j];  }
    t1=1;
    while(n2--)
    {
    
    
        cin>>sign1>>sign2;
        if(sign1==0)
        t1=pp[t1][sign2];
        else if(sign1==1)
        {
    
    stor[sign2-1][0]=t1;
        printf("%d\n",t1);}
        else if(sign1==2)
        {
    
    
            t1=stor[sign2-1][0];
        }
    }
    printf("%d\n",t1);
    return 0;
}

但是还有几个没过,不过没想到居然L2的题用数组就可以解开三个样例
在这里插入图片描述
第二版考虑改用变长数组,STL容器,vector
在这里插入图片描述
哇,全过了,真棒,看来以后真的不能被吓到,慢慢来,耐心点,后面的题目选着写是可以做到的。

#include<bits/stdc++.h>
using namespace std;
int main(){
    
    
    ios::sync_with_stdio(false);
    //感觉好像就凭数组就可以解出,只要思路清晰就没问题
    int n1,n2,m1,t1,tmp,sign1,sign2;
    cin>>n1>>n2;
    vector<int> pp[n1+1];
    int stor[n1]={
    
    0};
    for(int i=1;i<=n1;i++)
    {
    
     cin>>m1;
     for(int j=1;j<=m1;j++)
     {
    
      cin>>tmp;
        pp[i].push_back(tmp);
    } }
    t1=1;
    while(n2--)
    {
    
    
        cin>>sign1>>sign2;
        if(sign1==0)
        t1=pp[t1][sign2-1];
        else if(sign1==1)
        {
    
    stor[sign2-1]=t1;
        printf("%d\n",t1);}
        else if(sign1==2)
        {
    
    
            t1=stor[sign2-1];
        }
    }
    printf("%d\n",t1);
    return 0;
}

带有注释的全过版本:

#include<bits/stdc++.h>
using namespace std;
int main(){
    
    
    ios::sync_with_stdio(false);
    //感觉好像就凭数组就可以解出,只要思路清晰就没问题
    int n1,n2,m1,t1,tmp,sign1,sign2;
    cin>>n1>>n2;
    vector<int> pp[n1+1];//用来储存设置的关卡跳转
    int stor[n1]={
    
    0};//用来储存,存档的关卡
    for(int i=1;i<=n1;i++)
    {
    
     cin>>m1;
     for(int j=1;j<=m1;j++)
     {
    
      cin>>tmp;
        pp[i].push_back(tmp);//变长数组有利于减少空间,也防止段错误
    } }
    t1=1;
    while(n2--)
    {
    
    
        cin>>sign1>>sign2;
        if(sign1==0)
        t1=pp[t1][sign2-1];//操作的时候,知道到哪个关卡了
        else if(sign1==1)
        {
    
    stor[sign2-1]=t1;
        printf("%d\n",t1);}//存档,存下当前关卡
        else if(sign1==2)
        {
    
    
            t1=stor[sign2-1];//读第几档
        }
    }
    printf("%d\n",t1);
    return 0;
}
//看似好像要考虑数组的横坐标和纵坐标 ,实际上一直只是横坐标,纵坐标 只是横坐标的一个跳转

Guess you like

Origin blog.csdn.net/qq_51976555/article/details/117905159