XMUT 1107 牲口棚的安全

XMUT 1107 牲口棚的安全_第1张图片

XMUT 1107 牲口棚的安全_第2张图片


       现场比赛的时候,我最开始想到的思路是对输入的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的话,还真不想去写优化版的代码了……


你可能感兴趣的:(ACM,校第五届程序设计大赛)