Shuffle'm Up POJ - 3087 简单模拟 + 状态记录

这题很简单,就是读题有点费劲。
每次操作都只有一个后继状态,每次执行的操作都相同,所以所有的状态就像一个圈一样进行循环,我计算后发现,当长度为 n 时,循环周期最多为2n,最多100个字符,所以循环周期最多200次(使用map 标记一下是否访问过该状态)。
最多 1000 个 test case,复杂度最大不超过 2e5 ,绝对不会t的。

那么问题来了,我怎么看出来一个搜索题是个搜索题呢?
我觉得最重要的是状态转移,关注前驱状态和后继状态之间的转移关系,别忘了 从宏观角度考察一下所有状态

#include<iostream>
#include<string>
#include<map>

using namespace std;
map<string,int> mp;
int n;

int main()
{
    int t;
    int flag;
    int counts;
    cin>>t;
    string a;
    string b;
    string c;
    string d;
    string goal;
    ios::sync_with_stdio(false);
    for(int ps =0;ps< t;ps++)
    {
        cin>>n;
        cin>>a;
        cin>>b;
        cin>>goal;
        c="";
        flag=0;
        counts =1;

        for(int i=0;i<n;i++)
        {
            c+=b[i];
            c+=a[i];
        }
//        cout<<c<<endl;
        if(c==goal)
        {
            cout<<ps+1<<" "<<1<<endl;
            continue;
        }
        //cout<<"gagag    "<<c<<endl;

        mp.clear();
        //cout<<"清空 字典  "<<mp.size()<<endl;
        while(1)
        {
            d="";
            for(int i=0;i<n;i++)
            {
                d+= c[n+i];
                d+=c[i];
            }
            //cout<<d<<endl;
            counts++;
            if(d ==goal)
            {
                flag=1;
                break;
            }
            if(mp.find(d)!=mp.end())break;
            else mp[d] = 1;
            c =d;


        }
        cout<<ps+1<<" ";
        if(flag==1)cout<<counts<<endl;
        else cout<<-1<<endl;

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jackcily/article/details/83042084