• 1003 我要通过!(20)(20 分)


    “答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

    得到“答案正确”的条件是:

    1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
    2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
    3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。

    现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。

    输入格式: 每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。

    输出格式:每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。

    输入样例:

    8
    PAT
    PAAT
    AAPATAA
    AAPAATAAAA
    xPATx
    PT
    Whatever
    APAAATAA
    

    输出样例:

    YES
    YES
    YES
    YES
    NO
    NO
    NO
    NO

    分析: 关于上面正确字符串的定义, 这是典型的递归定义, 第1点和第2点是初始条件, 第3点是归纳条件. 来说下显然可以得到的结论,
    正确字符串必定有且只有一个P和一个T, 其余的都是A, 并且P在T的前面, 更具体地, 正确字符串必定是A...APA...ATA...A的模式.
    仔细观察第3点, aPbATca和aPbTc的区别在于前者的P和T之前多了个A, T之后多了a, 可以想象, 面对一个给定字符串, 先要数出P之前有多少个A,
    P和T之间有多少个A, T之后有多少个A, 首先判断是否符合第2点, 不符合就在T之后去掉与
    P之前相同数量的A, 在P和T之间去掉一个A,
    然后再判断剩下来的字符串是否为正确字符串, 重复若干次去掉的操作, 最后肯定归结到是否符合第2点. 但是有更好的办法,
    既然每次都是去掉一个中间A和一个尾部a, 想象最后得到的aPATa形式, 将P前面A的数量设为x, P和T之间A的数量设为1, 那么每增加一个中间A就增加一个尾部a,
    假设增加y次得到给定的字符串. 对于给定的字符串, P前面A的数量仍为x, P和T之间A的数量变为1+y, T之后A的数量变为x+xy=x(1+y), 那么给了一个字符串,
    判断 中间A的数量 是否大于0而且 T之后A的数量 是否等于 P前A的数量 乘以 P和T之间A的数量 就可以了.

    接着上代码:
    #include <cstdio>
    #include <cstdlib>
    #include <string>
    #include <iostream>
    using namespace std;
    
    const string rightAnswer = "YES";
    const string wrongAnswer = "NO";
    
    bool isRight(string s)
    {
    	// count len_front_A_string
    	size_t index_of_A = 0; 
    	while(index_of_A<s.length() && 'A' == s[index_of_A]) index_of_A++;
    	if(index_of_A==s.length() || 'P' != s[index_of_A]) return false;
    	size_t len_front_A_string=index_of_A;
    	// count len_middle_A_string
    	index_of_A++;
    	size_t len_middle_A_string = 0;
    	while(index_of_A<s.length() && 'A'==s[index_of_A]) 
    	{
    		index_of_A++;
    		len_middle_A_string++;
    	}
    	if(index_of_A==s.length() || 'T' != s[index_of_A]) return false;
    	// count len_back_A_string
    	index_of_A++;
    	size_t len_back_A_string = 0;
    	while(index_of_A<s.length() && 'A'==s[index_of_A]) 
    	{
    		index_of_A++;
    		len_back_A_string++;
    	}
    	if(index_of_A!=s.length()) return false;
    	// 
    	if(len_middle_A_string>0 && len_front_A_string*len_middle_A_string==len_back_A_string)
    	{
    		return true;
    	}else
    	{
    		return false;
    	}
    }
    
    
    int main()
    {
    	//freopen("input.txt", "r", stdin);
    	int n;
    	cin>>n;
    	string inputStr;
    	for(int i=0;i<n;i++)
    	{
    		cin>>inputStr;
    		if(isRight(inputStr))
    		{
    			cout<<rightAnswer<<endl;
    		}else
    		{
    			cout<<wrongAnswer<<endl;
    		}
    	}
    	
    	return 0;
    } 
    

      

     




  • 相关阅读:
    Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
    在执行Action之间检验是否登录
    链接服务器使用方法
    easyui-treegrid节点选择
    SQLServer 存储过程详解
    转载:SQL Server编程基本语法
    【转】SQL Server编程游标
    机器学习14—SVD学习笔记
    机器学习13—PCA学习笔记
    FP Tree算法原理总结(转载)
  • 原文地址:https://www.cnblogs.com/Luxuer/p/9347636.html
Copyright © 2020-2023  润新知