ACM水题-AB串(AC,分情况,要小心陷阱,两种思路)
来源:互联网 发布:啊哈!算法pdf 编辑:程序博客网 时间:2024/05/18 04:12
AB串
Time Limit:1000MS Memory Limit:32768K
Description:
对一个AB串,进行一定的操作,每次操作只能交换相邻的字符。求最少的操作数使得相同的字母都在同一边,如AAAAABBBBB。Input:
每一行给出一个AB串,长度不超过100,且A、B都含有,不含其它字符Output:
每一行一个答案,输出最少操作次数。Sample Input:
ABA
Sample Output:
1
Source:
李广为
链接:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1518
/*--------------------------------------------------------------------------------WA了,原因就是中陷阱了,ABA,操作步数1,但是结果有可能有两种,ABB,BBA。。我的代码是以ABBB这样为基础的,所以错了。。。明天再改。。下午要复习了,要考试了。。ACM月赛也木有玩了~~~ AC,分两种情况来讨论,一种就是A左B右,一种就是B左A右,两个之中求最小的那个。。15MS--------------------------------------------------------------------------------*/#include<stdio.h>#include<string.h>char szStr[104] ;int nMinStep(int nStart, int nFirst , char chLeft, char chRight) ; int main(void){int i = 0 ;int nFirstB = 0 ;int nFirstA = 0 ;int nMinAB = 0 ;int nMinBA = 0 ;int nMinTotal = 0 ;char chTemp = 0 ;int iA = 0 ;int iB = 0 ;while(scanf("%s",szStr) != EOF){nMinTotal = 0 ;nFirstB = -1 ;nFirstA = -1 ;i = 0 ;while(szStr[i] != '\0'){if(nFirstA >= 0 && nFirstB >= 0){break ;}else if('A' == szStr[i] && nFirstA < 0){nFirstA = i ;iA = i + 1 ; }else if('B' == szStr[i] && nFirstB < 0){nFirstB = i ;iB = i + 1 ;}i++ ;}nMinAB = nMinStep(iB,nFirstB,'A','B') ;nMinBA = nMinStep(iA,nFirstA,'B','A') ;nMinTotal = nMinAB < nMinBA ? nMinAB : nMinBA ;printf("%d\n",nMinTotal) ;}return 0 ;}int nMinStep(int nStart, int nFirst , char chLeft, char chRight) {int i = nStart ;int j = 0 ; int nTotal = 0 ;char szTempStr[104] ;char chTemp ;strcpy(szTempStr,szStr) ;while(szTempStr[i] != '\0'){if(chRight == szTempStr[i]){i++ ;}else if(chLeft == szTempStr[i]){chTemp = szTempStr[i] ;for(j = i ; j > nFirst ; --j){szTempStr[j] = szTempStr[j-1] ;nTotal++ ;}szTempStr[nFirst] = chTemp ;nFirst++ ;}}return nTotal ;}
/*----------------------------------------------------------------------------------------第二种方法:其实就是看看排前要移动的字母前面的互异字母有多少个。比如ABBBAA如果A在左,B在右的话。那个在第二个A的前面有3个B,所以A最少要移动3次。同样道理排在第3个A前面也有3个B,所以最小也要移动3次,所以这种情况下是6步。如果B在右,A在左的话。那么排在第一个B前面有一个A,所以第一个B最少要移动1次。同样道理第二、第三个B都至少要移动1次。所以总共是三次。 我的算法思路就是遍历一次数组,统计上述算法需要的信息。即在发现A之前,排在它前面有多少个B或者在发现B之前,排在它前面有多少个A。 所以相对第一种算法来说,时间复杂度降低了一个常数因子,为O(n),前一种算法就算不计找到第一个A,B,不计复制字符串的时间至少也要O(2n)的时间。前一种算法的总时间为 :15MS而这一种只需要: 4 MS----------------------------------------------------------------------------------------*/#include<stdio.h>char szStr[104] ;int main(void){int i = 0 ;int nFirstB = 0 ;int nFirstA = 0 ;int nMinAB = 0 ;int nMinBA = 0 ;int nMinTotal = 0 ;int nASum = 0 ;int nBSum = 0 ;int fFA = 0 ;int fFB = 0 ;while(scanf("%s",szStr) != EOF){nMinTotal = 0 ;nFirstB = -1 ;nFirstA = -1 ;nMinAB = nMinBA = 0 ;nASum = nBSum = 0 ;fFA = fFB = 0 ;i = 0 ;while(szStr[i] != '\0'){if('A' == szStr[i]){if(nFirstA < 0){nFirstA = i ;nASum++; }else {nASum++ ;}if(nFirstB >=0){nMinAB += nBSum ;}}else if('B' == szStr[i] ){if(nFirstB < 0){nFirstB = i ;nBSum++;}else{nBSum++ ;}if(nFirstA >= 0){nMinBA += nASum ;}}i++ ;}nMinTotal = nMinAB < nMinBA ? nMinAB : nMinBA ;printf("%d\n",nMinTotal) ;}return 0 ;}
/*--------------------------------------------这一个方法是建立在第二种方法上的,但是没有使用数组,所以空间复杂度应该有所下降,但是测试结果却和有数组的一样。。。。。而且在最后一组测试数据后面竟然木有换行符,直接EOF,所以我的代码最后还要加上一个特殊处理时间:4MS,190K-------------------------------------------- */#include<stdio.h>int main(void){int nFirstB = 0 ;int nFirstA = 0 ;int nMinAB = 0 ;int nMinBA = 0 ;int nMinTotal = 0 ;int nASum = 0 ;int nBSum = 0 ;int fNewLine = 1 ;char ch = '\0' ;while((ch = getchar()) != EOF){if(1 == fNewLine){nMinTotal = 0 ;nFirstB = nFirstA = -1 ;nMinAB = nMinBA = 0 ;nASum = nBSum = 0 ;}if('\n' == ch){nMinTotal = nMinAB < nMinBA ? nMinAB : nMinBA ;printf("%d\n",nMinTotal) ;fNewLine = 1 ;continue ;}fNewLine = 0 ;if('A' == ch){if(nFirstA < 0){nFirstA = 1 ;nASum++; }else {nASum++ ;}if(nFirstB >=0){nMinAB += nBSum ;}}else if('B' == ch){if(nFirstB < 0){nFirstB = 1 ;nBSum++;}else{nBSum++ ;}if(nFirstA >= 0){nMinBA += nASum ;}}}/*加上这一行是因为,那个最一个测试数据后面竟然不加换行符...*/nMinTotal = nMinAB < nMinBA ? nMinAB : nMinBA ; printf("%d\n",nMinTotal) ;return 0 ;}
- ACM水题-AB串(AC,分情况,要小心陷阱,两种思路)
- ACM水题-Differing sequence(AC,递归,分情况)
- ACM水题-合法字符串 (AC,递归遍历,分情况,代码比较长)
- ACM水题-迷宫(AC,DFS)
- 创业小心三种诈骗陷阱
- C#linq和lamda两种写法返回的集合中的对象元素引用情况不同,循环计算值要小心
- uva10905同一思路的两种做法,前一种WA,后一种AC
- UVA 1450 Airport (二分)PS:两种思路的改错,想AC就看我!!!
- UESTC 1034 AC Milan VS Juventus 分情况讨论
- http://acm.pku.cn/JudgeOnline/problem?id=1141两种AC方法
- 小心,StrConv有陷阱!
- 小心'溢出'陷阱
- 选购二手笔记本电脑小心陷阱
- 小心Comparator陷阱
- 小心陷阱--% of C
- 小心arrays.aslist陷阱
- ZJU/ZOJ Deque and Balls 3929 计数:小的情况对总情况的贡献。 小心mod运算陷阱
- 山东省第八届ACM省赛 J 题 company(两种思路) 解答
- hibernate 用SQLQuery/HQL查询的 查询 记录是否存在。
- 楼房开盘
- linux进程状态浅析
- 《钢铁侠》等电影中的image based lighting和physical shading
- ATL技术内幕 第二部分
- ACM水题-AB串(AC,分情况,要小心陷阱,两种思路)
- Markdown: Basics (Markdown快速入门)
- IO知识点总结2
- android自定义开机动画文件存放位置
- 《unix环境高级编程》中 竞争条件 的解决(setjmp longjmp)
- 用Android 关于PopupMenu的
- Android 线程 实例介绍
- 基于HZK16的汉子显示技术
- 【Java】利用反射hacking java程序