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:

李广为

Status  Submit

 

链接: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 ;}


 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 业主对我们提出批评意见时怎么办 向环保局投诉被公司发现了怎么办 在政务大厅上班被群众投诉怎么办 政府下发的文件通知不履行该怎么办 给私人老板开车不给工资怎么办 给个体老板开车不给工资怎么办 户口转走在人才市场的档案怎么办 外来媳妇转上海户口没有档案怎么办 公务员考试笔试差9分面试怎么办 想从事人事方面的工作没经验怎么办 教师资格考试后户籍转走认定怎么办 总经理离职了作为高管的我怎么办 企业换总经理想换供应商应该怎么办 换了晶振时间还快怎么办 职场两个人都想要你的情况下怎么办 造价起步工资太低又结婚了怎么办 3d保存时写入文件出错怎么办 无经验想在工地承包点小活怎么办 一级建造师挂靠后中标后怎么办 用360对系统修补漏洞很慢怎么办 如果美国和俄罗斯开战中国会怎么办 戴牙冠前临时补牙材料掉了怎么办 设备间在业主家里每次上锁怎么办 成都安全员证原件丢了并过期怎么办 记不施工员证书号了怎么办 优易学车学员版登录不了怎么办 先科移动dvd主板坏了怎么办 离职单位不出劳动解除书怎么办 离职后一级建造师注册证怎么办 京牌货车报废挂靠公司不给办怎么办 二建挂靠注册证书到期了怎么办 二建证书挂靠公司不给钱怎么办 二建拿到证书原单位不解锁怎么办 凯云软件清单锁定只读了怎么办 苹果笔记本鼠标触摸板没反应怎么办 苹果笔记本键盘和触摸板失灵怎么办 苹果手机输入密码显示已停用怎么办 苹果7p手机刷机黑屏了怎么办 苹果5s来电接听屏幕卡顿怎么办? 手机摔了一下触屏失灵怎么办 小米手机摔了一下触屏失灵怎么办