1. 程式人生 > >Shuffle'm Up POJ - 3087 簡單模擬 + 狀態記錄

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;
}