现场比赛的时候,我最开始想到的思路是对输入的C个字符串进行全排列,然后截取前L个字符,测试一个个条件是否满足,但代码敲出雏形测试时,不知道哪里出问题,数据没多大就要跑好几秒,我觉得这样不行,会TLE。C=20,算法运算量最大达到20!=2.4e18,。
于是想中规中矩的,把元音和辅音分开存储在两个字符串里,再分别进行全排列。但这样程序写起来又相当麻烦,写了很久都没写出来。如何排列组合,自己思路也不清晰,无从下手。
赛后总结,本想把那份中规中矩的代码完成,但是思路上还是想不清要如何实现。我就抱着测试一下的态度,写了份最没效率的代码。
#include <iostream> #include <algorithm> using namespace std; int CountIf(char ch[],int N) // 统计N内元音个数 { int i,n=0; for(i=0;i<N;i++) { switch(ch[i]) { case 'a':case 'e':case 'i': case 'o':case 'u':n++; } } return n; } int main() { int i, L, C, n; cin >> L >> C; char ch[25],str[25],logo[25],logo2[25]; for(i=0;i<C;i++) scanf(" %c",&ch[i]); logo2[L] = logo[L] = ch[i] = '\0'; sort(ch, ch+C); do { n = CountIf(ch,L); if((n>0)&&(L-n>1)) { for(i=0;i<L;i++) str[i] = ch[i]; str[i] = '\0'; strcpy(logo,str); sort(logo, logo+L); if(!strcmp(logo,str)) { if(strcmp(logo2,str)) strcpy(logo2,str), cout << str << endl; } } }while(next_permutation(ch,ch+C)); return 0; }
1)录入C个字符至字符串ch,对ch排序
2)统计ch的前L个字符有多少个元音,记为n
3)判断n>=1,且L-n>=2,满足则进入4),否则跳至第6)步
4)用str存储ch的前L个字符的副本,logo存储str里字符的排序后版本,logo2存储上一次输入到屏幕的字符串
5)只有当str==logo,且str!=logo2时,才输出str,且更新logo2
6)计算ch的下一个字典序,并返回第2)步,直至字典序结束
然后这样的代码竟然AC了……这数据真是要多水有多水啊!不过这样能AC的话,还真不想去写优化版的代码了……