1. 程式人生 > >POJ 3087 Shuffle'm Up

POJ 3087 Shuffle'm Up

n) scanf gpo tdi 交叉連接 字符串 else 字符 stdio.h

題意:多組數據,一個長度n,然後兩行字符串s1,s2,還有一行是給定的目標字符串,把s2,s1交叉連接起來之後(s2第一個字符在最下邊),不斷翻轉(每次都是上邊一半和下邊一半換),直到找到給你的目標字符串。輸出所需步數。若無法達到,也就是無限反轉循環,弄不出來給你的目標字符串,輸出-1;

搜索的話比較麻煩,寫了一半放棄了,數組模擬比較簡單,但是也有難點,就是你需要標記出現過的字符串來決定是否已經重復並且不是目標字符串,這個地方不控制的話就是死循環。

用到了map庫函數,這也是第一次用map函數,比較容易理解,用起來很方便,可以標記出現過的字符串,詳細用法代碼裏就能看明白啦。(數據不大,不用開全局數組,開了應該也不會錯);

代碼如下:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<map>
using namespace std;

int main()
{
    int m,n,i,j,k,cas=0,step;
    scanf("%d",&n);
    while(++cas<=n)
    {
        scanf("%d",&m);
        char s1[205],s2[205],s12[410];
        
        scanf(
"%s%s%s",s1,s2,s12); map<string,bool>vist;//此處為map函數用法,以後字符串標記可以考慮用這個 vist[s12]=true; step=0; while(true) { char s[410]; k=0; for(i=0; i<m; i++)//第一次就是S2,S1交叉存入S數組,這也算一步(從S2第一個開始存,題目要求) { s[k++]=s2[i]; s[k
++]=s1[i]; } s[k]=\0;//此處必須要加‘\0’作為字符串結束標誌,切記,如不加就是WA,不加的話中間翻轉的時候好像會出錯,具體到哪錯了沒辦法顯示出來,自己再琢磨琢磨 step++; if(!strcmp(s,s12)) { printf("%d %d\n",cas,step); break; } else if(vist[s]&&strcmp(s,s12))//若出現重復的但是和目標字符串不同,就不必再往下反轉了,表示無法弄出來目標字符串 { printf("%d -1\n",cas); break; } vist[s]=true;//出現過的都標記 for(i=0; i<m; i++) s1[i]=s[i]; s1[i]=\0; for(k=0; i<m*2; i++,k++) s2[k]=s[i]; s2[i]=\0; } } return 0; }

POJ 3087 Shuffle'm Up