?
解析:
PAT都必须有,P和T有且只有一个,P和T之间必须有A 这个有一个规律,即a * b=c。可以参看输入样例中的PAAT (0x2=0)和 AAPATAA (2x1=2)和 AAPAATAAAA(2x2=4)。 APAAATAA不满足,输出NO
?思路:
(1)因为是n(n<10)个字符串 每个字符串长度不超过100,所以是个n行100列的数组,是个很大的数组,最开始我直接用静态二维数组a[10][100]调试时会爆栈,所以我选择用二维数组动态分配(记得在最后要free)。
(2)大体的一个思路
判断是不是有且只有一个P和T,并且判断T是否在P的后面
P前面的A进行计数在变量cnt1中,如果P前面有除A以外的字符直接return 0
?PT之间的A进行计数在变量cnt2中,如果PT之间有除A以外的字符直接return 0
T之后的AA进行计数在变量cnt3中,如果T后面有除A以外的字符直接return 0
判断cnt2是否等于0,如果等于0就代表着中间无A,return 0 ,如果cnt2不等于0则继续
判断cn1 x cn2 是否等于cn3,等于则return 1 ,不等则return 0
代码:
#include <stdio.h>
#include <stdlib.h>
int IsPass(char **ch,int num);
int main(){
int cnt1,cnt2,cnt3,num,n,len[10];
char c;//临时保存getchar读取字符的变量
cnt1=0;cnt2=0;cnt3=0;
scanf("%d",&num);
char **pat;//动态分配二维数组
pat=(char**)malloc(num*sizeof(char*));
for(int i =0;i<num;i++){
pat[i]=(char*)malloc(sizeof(char)*100);
}
getchar();//缓冲输入num之后的回车\n
for (int i=0;i<num;i++){//将每一行的字符串的字符一个一个存进数组中
n=0;
while((c=getchar()) !='\n'){
pat[i][n]=c;
n++;
}
len[i]=n;//将每一行的字符长度存入len数组,方便之后确定遍历数组所用for的次数
}
int IsPass(char **ch,int row){
int indexP,indexT,numP,numT,cnt1,cnt2,cnt3;
indexP=0;indexT=0;numP=0;numT=0;cnt1=0;cnt2=0;cnt3=0;
char unit;//动态二维数组参数传递调用方法*(*(ch+row)+column); ch[row][column]
for (int i=0;i<len[row];i++){//查找P和T的位置和个数
unit = *(*(ch+row)+i);
if (unit == 'P'){
indexP=i;
numP++;
}else if(unit == 'T'){
indexT=i;
numT++;
}//else if(unit == '\r'){break;}
}
if ( ( (numP==1) && (numT==1) ) && (indexT>indexP) ){//判断是不是有且只有一个P和T
for (int i=0;i<indexP;i++){//判断P前面A的个数并将个数返回到cnt1
unit = *(*(ch+row)+i);
if (unit == 'A'){cnt1++;}else{return 0;}
}
for (int i=indexP+1;i<indexT;i++){//判断P和T之间A的个数并将个数返回到cnt2
unit = *(*(ch+row)+i);
if (unit == 'A'){cnt2++;}else{return 0;}
}
for (int i=indexT+1;i<len[row];i++){//判断T之后A的个数并方将个数返回到cnt3
unit = *(*(ch+row)+i);
if (unit == 'A'){cnt3++;}
else {return 0;}//if(unit == '\r'){break;}
//else if(unit != '\r'){return 0;}
}
}else{return 0;}
if (cnt2 == 0){//判断PT中间是否有A
return 0;
}else if( (cnt1) * (cnt2) == (cnt3) ){return 1;}else{return 0;}//有A再判断cnt1*cnt2是否等于cnt3
}
for (int i=0;i<num-1;i++){
if(IsPass(pat,i)){
printf("YES\n");
}else{printf("NO\n");}
}//n个字符串的前面的n-1个的判断
if (IsPass(pat,num-1)){
printf("YES\n");
}else{printf("NO\n");}//最后一个字符串的判断,不用输出\n
for (int i = 0; i < num; i++){
free(pat[i]);//释放列内存
}
free(pat);//释放行内存
return 0;
}
以下是取自他人的比较优秀的代码,点击跳转的原博客
#include <stdio.h>
#define ROW 10
#define COL 100+1
char lines[ROW][COL];
const char *yes = "YES\n";
const char *no = "NO\n";
// 判度字符串是否yes
int is_ok(const char *p){
int rst[3]= {0}; // r,s,t 三个整数
int offset = 0; // 遇到P的时候必须offset=0; 遇到T的时候必须offset=1
const char * cur = p;
// 扫描一遍字符串
while (*cur){
switch (*cur){
case 'A':
rst[offset]++;
break;
case 'P':
if (!offset){
offset++;
}else{
return 0;
}
break;
case 'T':
if (1==offset) offset++;
else return 0;
break;
default: // 遇到 PAT 之外的字符,返回 false
return 0;
break;
}
++cur;
}
// t = n + r*(s-1); 这些数字都为非负整数
int r = rst[0];
int s = rst[1];
int t = rst[2];
if (offset==2 && r>=0 && s>=1 && t==r*s) return 1;
else return 0;
}
int main(void){
int n;
scanf("%d",&n);
for (int i = 0;i<n;i++){
scanf("%s", lines+i); // 因为每行的字符串都不含空格,所以可以用scanf的%s读取
}
for (int i = 0; i<n; i++){
if (is_ok(lines[i])) printf(yes);
else printf(no);
}
return 0;
}
|