您的位置:首页 > 其它

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

2011-10-07 12:08 459 查看
#include<stdio.h>

#define	N	1000

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

}	iMaxQueue;

intmain(void)
{

	int	iTempSum=0;

	inti=0;
	
	intj=0;

	intt=0;

	intiCurBegPos=0;

	intiTemp=0;

	int	a
;

	intbFlag=0;

	iMaxQueueiMQ
;

	iMaxQueue	iMax,iMQTemp;

	while(1)
	{

		bFlag=0;

		scanf("%d",&t);

		if(0==t)
		{
			printf("000\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]);
		}

	}

	return0;
}


/*-----------------------------------------------------------------------------------------------------------------题目如下:ProblemDescription给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba,abba等Input输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S两组case之间由空行隔开(该空行不用处理)字符串长度len
<=110000Output每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.SampleInputaaaaababSampleOutput43----------------------------------------------------------------------------------------------------------------*//*------------------------------------------------------------------------------------------------------------------程序说明:
我的想法大致如下:1.先将索引为最左的元素,与索引为最右元素匹配。2.若第一次匹配的元素成功的话,保存此时成功的位置,记下回文可能的最大长度。则两边的索引向中间靠近一位。然后继续匹配。3.若第一次匹配不成功,则只有最右边的索引向左靠近一位,然后重新匹配。4.针对2的:若继续匹配失败,则最左端的索引复位(第一次匹配成功的位置)。最右端的索引复位(第一次匹配成功的位置),然后向中间进一位。长度之类的东西,全部复位。然后重新匹配。若继续匹配成功,一直到最后一位,则跳出循环。比较最大长度,最左端的索引向中间移一位,最右的索引复位为串的最后一位。表达能力有限,可能有些地方不是表述的那么清楚,请见谅,谢谢。PS:这一题没有通过。。。WA。。。------------------------------------------------------------------------------------------------------------------
*/#include<stdio.h>#include<string.h>#defineN120#defineMAXLEN1001intmain(void){intn=0;inti=0;intiMaxLen=1;intiBeg=0,iEnd=0,iTeBegPos=0,iTeEndPos=0,iTempLen=1;//索引变量和临时索引变量intbFlag=0;//开关变量,用来设置回文的最大长度intbOn=1;
//开关变量,用来设置回文的长度charszStr
[MAXLEN];//回文数组intt=0;intj=0;intLastBeg=0;//intLastEnd=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;}elseif(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("%dLmiddle=%dRmiddle=%d,Beg=%d,End=%d\n",iMaxLen,iBeg,iEnd,LastBeg,LastEnd);//eecc情况有bug}
//forreturn0;}







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

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

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



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

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



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



SampleInput
0051231232050775


SampleOutput
07712312320


Source
POJ


Recommend
Eddy

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

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

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

	总结:

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

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

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

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

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

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

intmain(void)
{
	charinput[1000];

	charszStrInt[100][1000];

	int	iResult[100];
	
	inti=0;
	
	intj=0;

	intbfinish=0;
	
	intk=0;

	inttemp=0;

	intt=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]);
	}

	return0;
}






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

	
ProblemDescription

给定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,输出整个序列的首尾元素。



SampleInput
6
-211-413-5-2
10
-101234-5-2337-21
6
5-83250
1
10
3
-1-5-2
3
-10-2
0


SampleOutput
201113
1014
1035
101010
0-1-2
000

HintHint
Hugeinput,scanfisrecommended.


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


Recommend
JGShining

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

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

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

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

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

	例如:

	Input:	-2-513-411-2
			----------------------------
	累加和:	-2-7621311
			----------------------------
减前0项的和:	-5841513
			----------------------------
减前1项的和:	1392018
			----------------------------
减前2项的和:-475
			----------------------------
减前3项的和:119
			----------------------------
减前4项的和:				-2
	
	所以,如图。。结果就是20.....

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

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

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

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

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

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

#include<stdio.h>

#define	N	1000

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

}	iMaxQueue;

intmain(void)
{

	int	iTempSum=0;

	inti=0;
	
	intj=0;

	intt=0;

	intiCurBegPos=0;

	intiTemp=0;

	int	a
;

	iMaxQueueiMQ
;

	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

	return0;
}










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

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

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

#define N 120
#define MAXLEN 110000

static charszStr[MAXLEN];

int main(void)
{
int n=0;

inti=0;

intiMaxLen=1;

intiBeg=0,iEnd=0,iTeBegPos=0,iTeEndPos=0,iTempLen=1;

intbFlag=0;

intbOn=1;

intt=0;

intiTemp=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;
}

elseif(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;
}
elseif(iMaxLen<iTemp)//增加了这一种情况,之前不对是因为对于这一种情况,abbefbba,得到的结果是1
{
iMaxLen=iTemp;
}
}

}

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

return0;
}





                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: