51Nod 1255 字典序最小的子串行

2021-07-22 05:29:12 字數 1746 閱讀 6395

acm模版

這道題大致思路不難,但是細節問題頗多,用兩種方法解題。

第一種,遍歷原串,如果答案串中沒有則往答案串中插入,如果答案串中第i個等於它,並且該字母往後查有第j個比他小,並且保證i和j之間的字母在原串中依然存在(保證可以被替換掉),則刪除第i個,後續向前遷移1,並在結尾處插入該字母。

第二種是利用棧原理實現,具體思路注釋很清晰,可以仔細研究一下。第二種較第一種效率略微高一些。

one:

#include 

#include

#include

using

namespace

std;

const

int maxn = 1e5 + 10;

const

int maxm = 27;

char s[maxn];

char ss[maxm];

int sflag[maxm];

bool ssflag[maxm];

void order(int pos, int len)

ss[len - 1] = s;

return ;

}int main(int argc, const

char * argv)

for (int i = 0; i < lens; i++)

for (int j = 0; j < lenss; j++)

if (ss[k] < s[i])

}break;}}

}std::cout

<< ss << '\n';

return

0;}

two:

#include 

#include

const

int maxn = 1e5 + 5;

const

int maxm = 128;

const

int maxl = 27;

char p[maxn + 1];

int c[maxm], apr[maxm], sapr[maxm];

int kind, min = -1, len, top = -1;

char ans[maxl], stack[maxl];

// 如果是當前的最小值,加入結果,並清空stack,更新最小值

// 如果不在stack,則更新stack

// 是該種類的最後乙個,直接將棧底至該元素加入結果,該元素至棧頂向下亞

int main()

for (int i = 'a'; i <= 'z'; ++i)

++kind; // 多少字母}}

for (int i = 0; kind > 0; ++i)

}for (int k = 0; k <= top; ++k)

top = -1;

}else

stack[++top] = p[i];

sapr[p[i]] = 1;

}if (--c[p[i]] == 0)

}for (++k, k2 = -1; k <= top; ++k)

top = k2;}}

}}puts(ans);

return

0;}

51Nod 1255 字典序最小的子串行

給出乙個由a z組成的字串s,求他的乙個子串行,滿足如下條件 1 包含字串中所有出現過的字元各1個。2 是所有滿足條件1的串中,字典序最小的。例如 babbdcc,出現過的字元為 abcd,而包含abcd的所有子串行中,字典序最小的為abdc。一開始看到這題就有乙個思路 如果現在找出來的答案末尾是x...

51 nod 1255 字典序最小的子串行

思路 分三種情況 1 棧空,直接將字母壓入。2 棧非空,當前字母大於棧頂元素,棧中未出現該字母,壓入棧。3 棧非空,當前字母小於棧頂元素,棧中未出現該字母,執行迴圈 棧頂元素大於當前字母,且後面還存在棧頂元素,彈出棧頂元素。最後壓入當前字母。include include include inclu...

51nod 1255 字典序最小的子串行

思路 貪心,迷之棧用法,對於字元,肯定是把小的字元排在前面,因此可以用棧來記錄串,用pre記錄a z出現的最後位置,將第乙個字元s 0 入棧,遍歷字串s 若字元s i 已入棧,則不做處理 若還沒入棧,則對s i 與棧頂字元比較 若s i 比棧頂字元大,則直接入棧,若s i 比棧頂字元小,按照貪心應該...