1. 程式人生 > >【NOJ1143】【演算法實驗二】【回溯演算法】字母轉換

【NOJ1143】【演算法實驗二】【回溯演算法】字母轉換

1143.字母轉換

時限:1000ms 記憶體限制:10000K  總時限:3000ms

描述

通過棧交換字母順序。給定兩個字串,要求所有的進棧和出棧序列(i表示進棧,o表示出棧),使得字串2在求得的進出棧序列的操作下,變成字串1。輸出結果需滿足字典序。

例如TROT 到 TORT:

[ i i i i o o o o i o i i o o i o ]

輸入

給定兩個字串,第一個字串是源字串,第二個字元是目標目標字串。

輸出

所有的進棧和出棧序列,輸出結果需滿足字典序。

#include <iostream>
#include <stack>
#include <string.h>

using namespace std;

stack <char>s;

int length; //字串長度
int in,out; //進棧/出棧次數

char start[1000];   //初始字串
char target[1000];  //目標字串

char tmp[1000];     //中間字串

char step[2000];    //記錄每一步的入棧/出棧操作

void dfs(int m);
bool ok();      //當前解能否符合要求
void output();  //輸出一組解

int main()
{
    while(cin>>start){
        cin>>target;
        int length1=strlen(start);
        int length2=strlen(target);

        in=out=0;

        cout<<'['<<endl;
        if(length1==length2){
            length=length1;
            dfs(0);
        }
        cout<<']'<<endl;
    }

    return 0;
}

void dfs(int m) //第m步操作,初始值為0
{
    if(m==length*2){
        if(ok())
            output();
        //else cout<<"ERROR"<<endl;
    }
    else{
        if(in<length){
            in++;
            step[m]='i';
            //cout<<'i'<<endl;
            dfs(m+1);
            in--;
        }
        if(out<in){
            out++;
            step[m]='o';
            //cout<<'o'<<endl;
            dfs(m+1);
            out--;
        }
    }
}

bool ok()       //當前解能否符合要求
{
    int i,j,k;
    for(i=0,j=0,k=0;i<length*2;i++){
        if(step[i]=='i')
            s.push(start[j++]);
        else{
            tmp[k++]=s.top();
            s.pop();
        }
    }
    for(int i=0;i<length;i++){
        if(tmp[i]!=target[i])
            return false;
    }
    return true;
}

void output()   //輸出一組解
{
    for(int i=0;i<length*2-1;i++)
        cout<<step[i]<<' ';
    cout<<step[length*2-1]<<endl;
    //cout<<tmp<<endl;
}

【後記】

1.這道題好難啊……可能因為沒有學過資料結構,對棧和C++都不太熟悉,還一昧的想著優化剪枝……昨晚寫這個被虐到凌晨,今天下午午覺睡醒了重新做才做出來……

2.啊啊啊啊啊今晚超級坑爹的把原始碼覆蓋掉了。。。親眼看到原始碼在自己眼前消失的感覺。。。太難受了,還好在oj上找到了QAQ……一定要備份啊備份!魂淡!