PAT (Basic Level) Practice 1003 我要通过!(两种解法)

乙级1003
在这里插入图片描述
在这里插入图片描述
这题和HOJ3788一样,故把那边的sample也拿过来:
在这里插入图片描述
题意好理解,就对条件3解释一下:
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
就相当于是先对aPbATca进行操作成aPbTc,这一个新的字符串再对条件1、2、3判断,对于这时候的条件3,aPbTc又是一个新的“aPbATca”,所以在条件3的操作方法一样

先介绍一下自己头次看到这题的想法,纯暴力模拟原题
先排除其它情况
1.如果有PAT之外的字
2.如果P、T出现2次以上或者1次都没出现+没有A
3.如果T前面不是A(判断P后面是不是A可能会有数组溢出的危险)
4.字符串长度不足3的

条件1,直接强行各元素一一对应就行
条件2,xPATx,也就是P左边的A和T右边的A数量一样即可
条件3,先拿出aPbATca,要找到a,bA,ca的位置,这时候我们就有了分开来的这三个组合,将它重组成aPbTc就可以了,然后组成的aPbTc再进行条件1、2、3的判断
纯模拟,对字符串的分解构成操作了很多,代码上有部分注释 还算能理解
模拟题就是要注意如果出什么样例与结果不符了的话,要一步一步慢慢调试,一个分号都不能打错!
AC代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int is1(char *p,int len);
int is2(char *p,int len);
int is3(char *p,int len);
int newlen; 
int main(){
	int n;
	cin>>n;
	char pat[102];
	while(n--){
		scanf("%s",&pat);
		int len = strlen(pat);
		if(is1(pat,len)||is2(pat,len)||is3(pat,len)){
//			printf("is1 = %d\n",is1(pat,len));
//			printf("is2 = %d\n",is2(pat,len));
//			printf("is3 = %d\n",is3(pat,len));
			
			printf("YES\n");
		}else
			printf("NO\n");
	}
	return 0;
}
int is1(char *p,int len){
	if(len==3){
		if(p[0]=='P'&&p[1]=='A'&&p[2]=='T') 
			return 1;
	}
	return 0;
}
int is2(char *p,int len){
	int p_pos = 0;
	for(int i = 0;i<len;i++){
		if(p[i]!='P'&&p[i]!='A'&&p[i]!='T')
			return 0;
		if(p[i]=='P'&&i+2<len&&p[i+1]=='A'&&p[i+2]=='T'){
			p_pos = i;
		}
	}
	if(p_pos+p_pos+3!=len||p_pos == 0)
		return 0;
	for(int i = 0;i<p_pos;i++){
//		printf("p[%d] = %c\n",i,p[i]);
		if(p[i]!='A')
			return 0;
		else{
			if(p[i]!=p[i+p_pos+3])
				return 0;
		}
	}
	return 1;
}
int is3(char *p,int len){//aPbATca --> aPbTc
	int p_pos=-1;
	int a_pos=-1;
	int t_pos=-1;
	int onlyt=0,onlyp=0;
	for(int i = 0;i<len;i++){
		if(p[i]!='P'&&p[i]!='A'&&p[i]!='T')
			return 0;
		if(p[i]=='P'){//只有一个P 
			if(onlyp){
				return 0;
			}
			p_pos = i;
			onlyp = 1;
		}
			
		if(i>=1&&p[i]=='T'){//只有一个T 
			if(onlyt){
				return 0;
			}
			t_pos = i;
			onlyt = 1;
			if(p[i-1]=='A'){//T前面必须是A 
				a_pos = i-1;
			}else return 0; //否则退出没写,一直卡着我的bug位置所在。。
			
		}
	} 
	if(p_pos==-1||a_pos==-1||t_pos==-1)
		return 0;
	newlen = a_pos+len-p_pos-t_pos;
	
//	printf("p_pos = %d    a_pos = %d    t_pos = %d    newlen = %d\n",p_pos,a_pos,t_pos,newlen);
	char aPbTc[newlen];
	
	int pos = 0;
	for(pos ; pos <= p_pos ; pos++){//aP
		aPbTc[pos] = p[pos];
//		printf("p[pos] = %c\n",p[pos]); 
	}
	
	
	
	int lenb = a_pos - p_pos - 1;
//	printf("a_pos = %d   p_pos = %d   lenb = %d \n",a_pos,p_pos,lenb);
	for(int i = 0;i<lenb;i++){  //aPbT
		aPbTc[pos] = 'A';
		pos++;
	}
	aPbTc[pos++] = 'T';
	
	int lenc = len - p_pos - t_pos - 1;
	
//	printf("lenc = %d\n",lenc);
	for(int i = 0;i<lenc;i++){
		aPbTc[pos++] = 'A';
	}
	
//	for(int i = 0 ;i<newlen;i++){
//		printf("%c",aPbTc[i]);
//	}
//	cout<<endl;
	
//	printf("is1 = %d\n",is1(aPbTc,len));
//	printf("is2 = %d\n",is2(aPbTc,len));
			
	if(is1(aPbTc,newlen)||is2(aPbTc,newlen)||is3(aPbTc,newlen)){
		return 1;
	}
	return 0;
}

再讲一下另一个思路:找规律
第一次看的时候看不出规律,第二次看的时候发现了……所以如果遇到一个非常复杂的模拟题可以先放一放,有可能这题会有特殊的规律
针对条件3,首先要明白aPbATca转换成aPbTc后,这个新的字符串也可能还是aPbATca的格式
然后针对这个操作再详细思考一下:
我们从aPbATca转换成aPbTc,实质上是去掉了b+A的一个A,以及c+a的一个a。
如果条件1、2不通过,继续条件3下去,每次都是去掉b+A的一个A,c+a的一个a
去掉最后,肯定是以条件1和条件2为出口出去,那就是说,去掉最后肯定是
xPATx的格式(x=null即条件1)
再将其转换成aPbTc,那就是此时我的B=一个A,a=c
然后往回推成aPbATca,最左边的a不变,每一次b加一个A,c加一个a
推回到原字符串,P和T之间我每加n个A,T后面的字符串内容就是n*a
那就是说 只要我的a*b = c 那它就是一个合格的字符串
AC代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int p_pos = -1;
int t_pos = -1;
int a_pos = -1;
int isright(char *a,int len){//字符串格式确认 
	int onlyp = 0;
	int onlyt = 0;
	for(int i = 0;i < len;i++){
		if(a[i]!='P'&&a[i]!='A'&&a[i]!='T') return 0;
		else{
			if(a[i]=='P'){
				if(onlyp)	return 0;
				else 		{onlyp = 1;	p_pos = i;}
			}
			if(a[i]=='T'){
				if(onlyt)	return 0;
				else {
					onlyt = 1;
					t_pos = i;
					if(a[i-1]=='A')	a_pos = i-1;
					else return 0;
				}
			}
		}
	}
	if(!onlyp||!onlyt)	return 0;
	return 1;
}
int main(){
	int n;
	cin>>n;
	char pat[102];
	while(n--){
		scanf("%s",&pat);
		int len = strlen(pat);
		int wellplay = 0; 
		if(isright(pat,len)){
			int lena = p_pos;
			int lenb = a_pos - p_pos - 1;
			int lenca = len - t_pos - 1;
			int lenc = lenca - lena;
			if(lenb*lena==lenc){
				wellplay = 1;
			}
		}
		if(wellplay)
			printf("YES\n");
		else
			printf("NO\n");
	} 
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/a656418zz/article/details/84311499