#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 ; }
ACM题目三道--------------一道超时了,两道WA
最新推荐文章于 2020-02-04 22:57:20 发布