ACM题目三道--------------一道超时了,两道WA

#include<stdio.h>



#define	N	1000

typedef	struct
{
	int	iBeg ;
	int	iEnd ;
	int	iSum ;

}	iMaxQueue ;





int main(void)
{

	int	iTempSum = 0 ;

	int i = 0 ;
	
	int j = 0 ;

	int t = 0 ;

	int iCurBegPos = 0 ;

	int iTemp = 0 ;

	int	a[N] ;   

	int bFlag = 0 ;


	iMaxQueue iMQ[N] ;

	iMaxQueue	iMax ,iMQTemp;


	while(1)
	{

		bFlag = 0 ;

		scanf("%d",&t) ;

		if(0 == t)
		{
			printf("0 0 0\n" );
			break ;
		}

	
		for(i = 0 ; i < t ; i++)
		{
			scanf("%d",&a[i]) ;
			iTempSum += a[i] ;
		
			if(a[i] > 0)
			{
				bFlag = 1 ;
			}
		}

		
	


		iMQ[0].iBeg = 0 ;
		iMQ[0].iEnd = 0 ;
		iMQ[0].iSum = a[0] ;

		iMax = iMQ[0] ;


		for(iCurBegPos = 0 , iTemp = a[0] , i = 1 ; i < t ; i++)   
		{
			iTemp += a[i] ;	
				
			iMQ[i].iSum = iTemp ;
			iMQ[i].iBeg = iCurBegPos ;
			iMQ[i].iEnd = i ;

			if(iMax.iSum < iTemp)            
			{
				iMax = iMQ[i] ;
			}                                 
	
		}

		for(j = 0 ,iCurBegPos = 1 ; j < t ; j++ , iCurBegPos++)   
		{
		
			for( i = j + 1 ; i < t ; i++)
			{
				iMQ[i].iSum -= iMQ[j].iSum ;
				iMQ[i].iBeg = iCurBegPos ;
	
				iMQTemp = iMQ[i] ;
			
				if(iMQTemp.iSum  >  iMax.iSum)
				{
					iMax= iMQTemp ;
				}
			}
		}

		if(!bFlag)
		{
			printf("0 %d %d\n",a[0],a[t-1]) ;
		}
		else
		{
			printf("%d %d %d\n",iMax.iSum,a[iMax.iBeg],a[iMax.iEnd]) ;
		}

	}

	return 0 ;
}

/* -----------------------------------------------------------------------------------------------------------------题目如下:Problem Description给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等Input输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S两组case之间由空行隔开(该空行不用处理)字符串长度len <= 110000Output每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.Sample InputaaaaababSample Output43---------------------------------------------------------------------------------------------------------------- *//* ------------------------------------------------------------------------------------------------------------------程序说明: 我的想法大致如下:1.先将索引为最左的元素,与索引为最右元素匹配。2.若第一次匹配的元素成功的话,保存此时成功的位置,记下回文可能的最大长度。则两边的索引向中间靠近一位。然后继续匹配。3.若第一次匹配不成功,则只有最右边的索引向左靠近一位,然后重新匹配。4.针对2的:若继续匹配失败,则最左端的索引复位(第一次匹配成功的位置)。最右端的索引复位(第一次匹配成功的位置),然后向中间进一位。长度之类的东西,全部复位。然后重新匹配。若继续匹配成功,一直到最后一位,则跳出循环。比较最大长度,最左端的索引向中间移一位,最右的索引复位为串的最后一位。表达能力有限,可能有些地方不是表述的那么清楚,请见谅,谢谢。PS:这一题没有通过。。。WA。。。------------------------------------------------------------------------------------------------------------------ */#include<stdio.h>#include<string.h>#define N 120#define MAXLEN 1001int main(void){int n = 0 ;int i = 0 ;int iMaxLen = 1 ;int iBeg = 0 , iEnd = 0 , iTeBegPos = 0 , iTeEndPos = 0 , iTempLen = 1 ; //索引变量和临时索引变量int bFlag = 0 ; //开关变量,用来设置回文的最大长度int bOn = 1 ; //开关变量,用来设置回文的长度char szStr[N][MAXLEN] ; // 回文数组int t = 0 ;int j = 0 ;int LastBeg = 0 ; //int LastEnd = 0 ; //while(gets(szStr[t])) //获取输入,不知道有木有理解错题目的意思,因为他没有指明要输入多少组数据,也没有说明要用EOF来结束。。。{t++ ; }for(j = 0 ; j < t ; j++){n = strlen(szStr[j]) ; iMaxLen = 1 ; //假设回文初始化长度最大为1for(i = 0 ; iMaxLen < n - i && i < n ; i++) {iBeg = i ; iEnd = n - 1 ;iTeBegPos = i ;iTeEndPos = n - 1 ; iTempLen = 1 ;for(bFlag = 0 , bOn = 1 ,iTempLen = iEnd + 1 - iBeg ; iBeg <= iEnd ; ){if(szStr[j][iBeg] == szStr[j][iEnd] && ( iBeg == iEnd || iBeg+1 == iEnd)) //判断回文是否匹配结束{bFlag = 1 ;break ;}else if(szStr[j][iBeg] == szStr[j][iEnd]) //继续匹配的情况{if(bOn){LastBeg = iBeg ; //调试作用LastEnd = iEnd ; //iTeEndPos = iEnd ;iTempLen = iEnd + 1 - iBeg ;bOn = 0 ;} iBeg++ ;iEnd-- ;} //else-ifelse //匹配失败的情况{iBeg = iTeBegPos ; iEnd = iTeEndPos - 1 ;iTeEndPos-- ;iTempLen = 1 ;bOn = 1 ;} //else} // forif(bFlag) //判断回文结束,比较最大的长度{if(iMaxLen < iTempLen){ iMaxLen = iTempLen ;}} //if} //forprintf("%d Lmiddle = %d Rmiddle = %d , Beg = %d , End = %d \n",iMaxLen,iBeg,iEnd,LastBeg,LastEnd) ; //eecc情况有bug} // forreturn 0 ;}



 

 

/*	------------------------------------------------------------------------------------------------------------------------------


Problem Description
输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数就是0)。

你的任务是:对这些分割得到的整数,依从小到大的顺序排序输出。


 

Input
输入包含多组测试用例,每组输入数据只有一行数字(数字之间没有空格),这行数字的长度不大于1000。  

输入数据保证:分割得到的非负整数不会大于100000000;输入数据不可能全由‘5’组成。

 

Output
对于每个测试用例,输出分割得到的整数排序的结果,相邻的两个整数之间用一个空格分开,每组输出占一行。

 

Sample Input
0051231232050775
 

Sample Output
0 77 12312320
 

Source
POJ 
 

Recommend
Eddy


  ------------------------------------------------------------------------------------------------------------------------------	*/





/*	--------------------------------------------------------------------------------------
	
	程序说明:

	利用strtok分割函数,然后atoi函数转换成整型,再利用冒泡排序排序。


	总结:

	其实这一题也没有什么好说的。只是在室友的提醒下,发现了有strtok这么这一个比较好用的函数。

	不过,这一个函数的使用比较奇怪。在第一次使用之后想要再使用,要传一个NULL给它。我想经过第一次

	分割的字符串,应该保存在某个地方,所以。。。猜测而已。。。


	PS:这一题也没有提交过。。自娱自乐而已。现在发现,原来这一个程序还没有完成。。


	-------------------------------------------------------------------------------------	*/



#include<stdio.h>
#include <string.h> 
#include<stdlib.h>

int main(void)
{
	char input[1000] ;

	char szStrInt[100][1000] ;

	int	iResult[100]  ;
	
	int i = 0 ;
	
	int j = 0 ;

	int bfinish = 0 ;
	
	int k = 0 ;

	int temp = 0 ;

	int t = 0 ;

	char *p ;

	gets(input) ;

	for(p = strtok(input,"5") ; p != NULL && i < 100 ; p = strtok(NULL,"5") ) 
	{
		strcpy(szStrInt[i],p) ;
		iResult[i] = atoi(szStrInt[i]) ;
		i++ ;
	}


	for(j = 0 ; j < i ; j++)
	{
		bfinish = 1 ;

		for(k = 0 ; k < i - j - 1; k++)  //要减一
		{
			if(iResult[k] > iResult[k+1])
			{
				temp = iResult[k+1] ;
				iResult[k+1] = iResult[k] ;
				iResult[k] = temp ;
				bfinish = 0 ;
			}
		}

		if(1 == bfinish)
		{
			break ;
		}
	}
	

	
	for(j = 0 ; j < i ; j++)
	{
		printf("%d ",iResult[j]) ;
	}



	return 0 ;
}


 

 

/*	------------------------------------------------------------------------------------------------------------------------
	题目:最大连续子序列

	
Problem Description

给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., 
Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个, 
例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和 
为20。 
在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该 
子序列的第一个和最后一个元素。

 

Input

测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( < 10000 ),第2行给出K个整数,中间用空格分隔。当K为0时,输入结束,该用例不被处理。

 

Output

对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元 
素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。 

 

Sample Input
6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 3 2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0
 

Sample Output
20 11 13
10 1 4
10 3 5
10 10 10
0 -1 -2
0 0 0

HintHint 
Huge input, scanf is recommended.
 

Source
浙大计算机研究生复试上机考试-2005年 
 

Recommend
JGShining








	------------------------------------------------------------------------------------------------------------------------------	*/


/*	-------------------------------------------------------------------------------------------------------------------------------
	程序说明:

	利用穷举法,将所有情况列出来了,在遍历的过程中顺便也将最大的子序列找出来。时间复杂度应该

	为O(n^2)( or O(!n)) ?

	遍历的做法,大概就是利用循环,累和每一项的和,然后再利用循环的减去前N项的和,找出最大的子序列 


	例如:

	Input:	 -2 -5 13 -4 11 -2
			 ----------------------------
	累加和:	 -2 -7 6  2  13 11
			 ----------------------------
减前0项的和:	-5 8  4  15 13
			 ----------------------------
减前1项的和:	   13 9  20 18
			 ----------------------------
减前2项的和:         -4   7  5
			 ----------------------------
减前3项的和:              11 9
			 ----------------------------
减前4项的和:				 -2
	
	  所以,如图。。结果就是20.....


	总结:想找出一种O(n)的方法,结果没有找成。想了一天整,结果只想到这一种方法。
		  还能说什么,渣渣的渣渣的渣渣的渣渣的渣渣的渣渣的~~~

		  本来,是想利用从两端向子序列中心靠近的方法,结果发现是行不通的。。。
		  子序列的两端有4种情况
		  + +
		  + -
		  - +
		  - -

		  本来,以为利用正负号,以及累加和之类的东西就可以做出来。。结果。。。。。

	百度过这一个问题,发现要用动态规则法来做。。好吧,我觉得我也要拿本算法导论来看看了。完全不知道有这一种方法。
	正确自己还没有意识到有这一种思想.
		   

	PS:	此题目没有去OJ那里判断过。。。我自己测试不出什么问题。。不过,估计也是通过不了的。可能有些数据没有测试得到。。
	

	------------------------------------------------------------------------------------------------------------------	*/


#include<stdio.h>



#define	N	1000

typedef	struct
{
	int	iBeg ;
	int	iEnd ;
	int	iSum ;

}	iMaxQueue ;





int main(void)
{

	int	iTempSum = 0 ;

	int i = 0 ;
	
	int j = 0 ;

	int t = 0 ;

	int iCurBegPos = 0 ;

	int iTemp = 0 ;

	int	a[N] ;


	iMaxQueue iMQ[N] ;

	iMaxQueue	iMax ,iMQTemp;


	while(1)
	{

		scanf("%d",&t) ;

		if(0 == t)
		{
			printf("Sum = 0 , Beg = 0 , End = 0\n" );
			break ;
		}

	
		for(i = 0 ; i < t ; i++)
		{
			scanf("%d",&a[i]) ;
			iTempSum += a[i] ;
		}

//	iMax.iBeg = 0 ;           //这部分可要可不要

//	iMax.iEnd = t-1 ;

//	iMax.iSum = iTempSum ;   //

		iMQ[0].iBeg = 0 ;
		iMQ[0].iEnd = 0 ;
		iMQ[0].iSum = a[0] ;

		iMax = iMQ[0] ;


		for(iCurBegPos = 0 , iTemp = a[0] , i = 1 ; i < t ; i++)   //累加和
		{
			iTemp += a[i] ;	
				
			iMQ[i].iSum = iTemp ;
			iMQ[i].iBeg = iCurBegPos ;
			iMQ[i].iEnd = i ;
	
		}//for

		for(j = 0 ,iCurBegPos = 1 ; j < t ; j++ , iCurBegPos++)   //依次减去前j项的和
		{
		
			for( i = j + 1 ; i < t ; i++)
			{
				iMQ[i].iSum -= iMQ[j].iSum ;
				iMQ[i].iBeg = iCurBegPos ;
	
				iMQTemp = iMQ[i] ;
			
				if(iMQTemp.iSum  >  iMax.iSum)
				{
					iMax= iMQTemp ;
				}//if
			}//for
		}//for


		printf("Sum = %d , Beg = %d , End = %d\n",iMax.iSum,iMax.iBeg,iMax.iEnd) ;
	

	}//while

	return 0 ;
}

 

 

 


 


 
/*	--------------------------------------------------
	之前wrong answer是因为abbefbba判断长度为1,所以在后面
	补上了对这一种情况的判断,不过依然没有通过,Time Limit Exceeded,
	超时了。。。。

	--------------------------------------------------	*/


#include<stdio.h>
#include<string.h>


#define		N	120
#define		MAXLEN	110000


static	char szStr[MAXLEN] ;     


int	main(void)
{
	int	n = 0 ;
	
	int i = 0 ;

	int iMaxLen = 1 ;

	int iBeg = 0 , iEnd = 0 , iTeBegPos = 0 , iTeEndPos = 0 , iTempLen = 1 ;   

	int bFlag = 0 ;    

	int bOn = 1 ;        

	int t = 0 ;

	int iTemp = 0 ;


	while(gets(szStr) && t < 120)
	{



		t++ ;


		n = strlen(szStr) ;      

		iMaxLen = 1 ;            

		for(i = 0 ; iMaxLen < n - i && i < n ; i++) 
		{
			iBeg = i ;                
			iEnd = n - 1 ;
	
			iTeBegPos = i ;
			iTeEndPos = n - 1 ;   

			iTempLen = 1 ;

			for(bFlag = 0 , bOn = 1 ,iTempLen = iEnd + 1 - iBeg ; iBeg <= iEnd ;  )
			{
				if(szStr[iBeg] == szStr[iEnd]  && ( iBeg == iEnd  || iBeg+1 == iEnd)) 
				{
					bFlag = 1 ;
					iTemp = iEnd + 1 - iBeg ;
					break ;
				}

				else if(szStr[iBeg] == szStr[iEnd])  
				{
					if(bOn)
					{

						iTeEndPos = iEnd ;
						iTempLen = iEnd + 1 - iBeg ;
						bOn = 0 ;
					
					} 

					iBeg++ ;
					iEnd-- ;

				}  
		
				else             
				{
					iBeg = iTeBegPos ; 
					iEnd = iTeEndPos - 1 ;
					iTeEndPos-- ;
					iTempLen = 1 ;
					bOn = 1 ;
				}  
		

			}   

	
			if(bFlag)                      
			{
				if(iMaxLen < iTempLen)
				{ 
					iMaxLen = iTempLen ;
				}
				else if(iMaxLen < iTemp)   //增加了这一种情况,之前不对是因为对于这一种情况,abbefbba,得到的结果是1
				{
					iMaxLen = iTemp ;
				}
			}   	

		}

		printf("%d\n",iMaxLen)  ; 
	}

	return 0 ;
}




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值