1 条题解

  • 0
    @ 2025-5-19 9:11:49

    题目解析

    题意分析

    这道题目模拟了扑克筹码的洗叠过程,要求计算从初始堆 S1S1S2S2 通过特定洗牌规则重组后,达到目标 S12S12 所需的最少洗牌次数。具体规则如下:

    1. 初始状态

      • 两个筹码堆 S1S1S2S2,每堆包含 CC 个筹码(1C1001 \leq C \leq 100
      • 每个筹码用大写字母 AA-HH 表示颜色
    2. 洗牌规则

      • 新建空堆 S12S12(最终包含 2×C2 \times C 个筹码)
      • 交替从 S2S2S1S1 的最底层开始取筹码:
        • ii 次操作(1iC1 \leq i \leq C):
          • S12[2i1]=S2[i]S12[2i-1] = S2[i]
          • S12[2i]=S1[i]S12[2i] = S1[i]
    3. 重组规则

      • 每次洗牌后,将 S12S12 拆分为:
        • S1S1:取 S12S12CC 个筹码(底层)
        • S2S2:取 S12S12CC 个筹码(顶层)
    4. 目标

      • 判断经过多少次洗牌后,S12S12 能等于目标序列
      • 若无法达成目标,则输出 1-1

    解题思路

    1. 模拟洗牌过程

      • 根据洗牌规则,每次洗牌生成新的 S12S12 序列
      • S12S12 拆分为新的 S1S1S2S2 用于下一次洗牌
    2. 检测循环

      • 使用集合记录每次洗牌后的 S1S1S2S2 状态
      • 如果状态重复出现,说明进入无限循环,无法达成目标
    3. 终止条件

      • 当前 S12S12 等于目标序列时,返回洗牌次数
      • 若洗牌次数超过 2×C2 \times C 次仍未达成目标,则认为无法达成

    #include<string.h>
    #include<string>
    #include<queue>
    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    using namespace std;
     
    string a,b,target;
    int num;
     
    int  dfs(string s1,string s2,int step){
        if(s1+s2==target)
              return step;
        string temp="";
        for(int i=0;i<num;i++)  temp=temp+s2[i]+s1[i];
        s1=temp.substr(0,num);
        s2=temp.substr(num,num);
        if(s1.compare(a)==0&&s2.compare(b)==0)
              return -1;
        else
              return dfs(s1,s2,step+1);
    }
     
    int main()
    {
        int Case;
        cin>>Case;
        for(int T=1;T<=Case;T++){
            cin>>num>>a>>b>>target;
            cout<<T<<' '<<dfs(a,b,0)<<endl;
        }
        return 0;
    }
     
    
    • 1

    信息

    ID
    2088
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者