【ACM】洛谷P1098-字符串的展開

題目描述

在初賽普及組的“閱讀程序寫結果”的問題中,我們曾給出一個字符串展開的例子:如果在輸入的字符串中,含有類似於“d-h”或者“4-8”的字串,我們就把它當作一種簡寫,輸出時,用連續遞增的字母或數字串替代其中的減號,即,將上面兩個子串分別輸出爲“defgh”和“45678"。在本題中,我們通過增加一些參數的設置,使字符串的展開更爲靈活。具體約定如下:

(1) 遇到下面的情況需要做字符串的展開:在輸入的字符串中,出現了減號“-”,減號兩側同爲小寫字母或同爲數字,且按照ASCII碼的順序,減號右邊的字符嚴格大於左邊的字符。

(2) 參數p_1:展開方式。
p 1=1時,對於字母子串,填充小寫字母;
p_1=2時,對於字母子串,填充大寫字母。這兩種情況下數字子串的填充方式相同。
p_1=3時,不論是字母子串還是數字字串,都用與要填充的字母個數相同的星號“*”來填充。

(3) 參數p_2:填充字符的重複個數。
p_2=k 表示同一個字符要連續填充k個。例如,當p_2=3時,子串“d-h”應擴展爲“deeefffgggh”。減號兩邊的字符不變。

(4) 參數p_3:是否改爲逆序:
p3=1表示維持原來順序,p_3=2表示採用逆序輸出,注意這時候仍然不包括減號兩端的字符。例如當p_1=1、p_2=2、p_3=2時,子串“d-h”應擴展爲“dggffeeh”。

(5) 如果減號右邊的字符恰好是左邊字符的後繼,只刪除中間的減號,例如:“d-e”應輸出爲“de”,“3-4”應輸出爲“34”。如果減號右邊的字符按照ASCII碼的順序小於或等於左邊字符,輸出時,要保留中間的減號,例如:“d-d”應輸出爲“d-d”,“3-1”應輸出爲“3-1”。


輸入輸出格式

輸入格式:

共兩行。

第1行爲用空格隔開的33個正整數,依次表示參數p_1,p_2,p_3。

第2行爲一行字符串,僅由數字、小寫字母和減號“-−”組成。行首和行末均無空格。

輸出格式:

共一行,爲展開後的字符串。

輸入輸出樣例

輸入樣例#1:
1 2 1
abcs-w1234-9s-4zz
輸出樣例#1:
abcsttuuvvw1234556677889s-4zz
輸入樣例#2:
2 3 2
a-d-d
輸出樣例#2:
aCCCBBBd-d

說明

字符串長度不超過100100
NOIP 2007 提高第二題


題解

思路

按照參數輸出是很簡單的,重點在於處理需要填充部分的內容。思路如下:

  1. 遍歷字符串,判斷‘-’是否需要處理
  2. 若需要處理,判斷是否爲相鄰字符
  3. 若是相鄰字符:什麼都不填充
  4. 若不是相鄰字符:保存需要填充的字符串
  5. 將字符串按照參數要求輸出
  6. 具體可看代碼註釋
代碼
#include<bits/stdc++.h>

using namespace std;

int main()
{
    /*
     * 思路:將需要填充的部分存入數組,然後按參數要求輸出。
     * p1,p2,p3 爲參數
     * c數組用來保存需要填充的字符串
     * len用來記錄c的長度
     */
    int p1,p2,p3,len=0;
    char begin,end,c[210];
    string str;

    cin>>p1>>p2>>p3;
    cin>>str;

    // 因爲第0位如果是‘-’,肯定不需要填充
    // 所以單獨輸出第0位,從第1位開始處理
    // 最後一位同理
    cout<<str[0];
    for (int i = 1; i < str.length()-1; ++i) {

        // 因爲怎樣填充都不影響兩端,所以如果不是‘-’可以直接打印
        if (str[i]!='-')
            printf("%c",str[i]);
        else{
            // 判斷需要處理的情況:同爲字母或數字且前小於後
            if ((str[i-1]>='a'&&str[i+1]<='z'&&str[i-1]<str[i+1])||
            (str[i-1]>='0'&&str[i+1]<='9'&&str[i-1]<str[i+1])){
                // 如果兩個字符不是相鄰的,則需要進行填充操作
                if (str[i+1]-str[i-1]>1){

                    // 將兩個字符之間的字符存入c數組
                    begin=str[i-1]+1;
                    end=str[i+1];

                    while (begin!=end){
                        for (int j = 0; j < p2; ++j)
                            c[len++]=begin;
                        begin++;
                    }

                    // 根據參數輸出
                    if (p1==3)
                        for (int j = 0; j < len; ++j)
                            printf("*");
                    else {
                        if (p1==2)
                            // 轉爲大寫
                            transform(c,c+len,c,::toupper);
                        if (p3==1)
                            for (int j = 0; j < len; ++j)
                                printf("%c",c[j]);
                        else
                            for (int j = len-1; j >= 0; --j)
                                printf("%c",c[j]);
                    }
                    // 初始化c數組;
                    len=0;
                }
                // 如果是相鄰的兩個字符,不做操作
            } else
                // 如果不是需要處理的‘-’,直接輸出‘-’
                printf("-");
        }
    }
    // 打印最後一位
    cout<<str[str.length()-1];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章