Codeforces 1303C Perfect Keyboard

給你一個字符串,要求你設計一種鍵盤,這個鍵盤用一行表示,其中在題目字符串中相鄰的字符,在你的鍵盤上也要相鄰。

我們用三個數組模擬一個雙向鏈表,pre[i]表示i字符前一個字符,nxt[i]表示i字符後一個字符,vis[i]標記i字符是否在鏈表中出現。

輸出的時候我們先把鏈表輸出,再把剩餘的隨便輸出就i行。

一個字符在鏈表出現過後,它的位置就是固定了的,如果前後爲空可以添加,但不能使它調到別的地方。不能出現循環鏈表。

因爲輸出的一行,某兩個相鄰的一定會被拆到鏈表兩頭,就不相鄰了。

具體細節在代碼註釋裏。

注意特判輸入只有一個字符的情況。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=205;
char s[N];
int pre[31],nxt[31],vis[31];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
       cin>>s;
       for(int i=0;i<26;i++) pre[i]=nxt[i]=-1,vis[i]=0;//初始化,-1代表前後沒有字符,0代表沒有出現過
       int l=strlen(s),flag=1;
       if(l==1) 
       {
           printf("YES\n");
           for(int i=0;i<26;i++) printf("%c",i+'a');
           printf("\n");
           continue;
       }
       vis[s[0]-'a']=1;//先把第一個字符標記上
       for(int i=1;i<l&&flag;i++)//從第二個字符開始,防止越界
       {
           int pree=s[i-1]-'a',tmp=s[i]-'a';//tmp表示當前字符,pree表示當前字符在輸入中的前一個字符
           if(pre[pree]==tmp||nxt[pree]==tmp) continue;//滿足題目要求,不需要再進行了
           flag=0;//標記字符是否成功放進鏈表
           if(vis[tmp]) break;//pree一定已經在鏈表中了,此時tmp也在鏈表中
//一種情況tmp兩端都有元素,上面已經判斷過,兩端是pree的已經continue了,到這裏說明不是
//一種情況tmp一端有元素,另一端爲空,如果讓空的這端與pree相連,就成循環了
//鏈表中不可能兩端都沒有元素
           if(nxt[pree]==-1)//tmp加在pree後面
           {
               nxt[pree]=tmp;
               pre[tmp]=pree;
               flag=1;
           } 
           if(flag==0&&pre[pree]==-1)//tmp加在pre前面
           {
               pre[pree]=tmp;
               nxt[tmp]=pree;
               flag=1;
           } 
           if(flag==1) vis[tmp]=1;//添加成功,標記在鏈表中出現了
       }
       if(flag==0) cout<<"NO"<<endl;//有節點添加不進去
       else
       {
            cout<<"YES"<<endl;
            for(int i=0;i<26;i++)
            {
                if(pre[i]==-1&&nxt[i]!=-1)//找到鏈表頭
                {
                    int x=i;
                    while(x!=-1) //輸出鏈表
                    {
                        printf("%c",x+'a');
                        x=nxt[x];
                    }
                    break;
                }
            }
            for(int i=0;i<26;i++) if(!vis[i]) printf("%c",i+'a');
            cout<<endl;
       }
    }
    //system("pause");
}

 

發佈了74 篇原創文章 · 獲贊 4 · 訪問量 5052
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章