CF113A Grammar Lessons 题解

一道模拟题。


题目传送门

题目意思:

给你一个句子,让你检查这个句子的语法是否正确。(语法请自行在题目中查看)


思路:

就是模拟。依次判断这个句子是否符合每一条语法即可。但是细节很多就因为细节我错了好多次!具体看代码注释。


代码:

#include
using namespace std;
const int N=1e6+10;
string a[N];
int cnt;
bool fh(string s)//判断单词是否合法
{
	int len=s.size();
	s=" "+s;
	if(s[len]=='s'&&s[len-1]=='o'&&s[len-2]=='i'&&s[len-3]=='l')
		return 1;
	if(s[len]=='r'&&s[len-1]=='t'&&s[len-2]=='e')
		return 1;
	if(s[len]=='s'&&s[len-1]=='i'&&s[len-2]=='t'&&s[len-3]=='i'&&s[len-4]=='n'&&s[len-5]=='i')
		return 1;
	if(s[len]=='a'&&s[len-1]=='l'&&s[len-2]=='a'&&s[len-3]=='i'&&s[len-4]=='l')
		return 1;
	if(s[len]=='a'&&s[len-1]=='r'&&s[len-2]=='t'&&s[len-3]=='e')
		return 1;
	if(s[len]=='s'&&s[len-1]=='e'&&s[len-2]=='t'&&s[len-3]=='i'&&s[len-4]=='n'&&s[len-5]=='i')
		return 1;
	return 0;
}
bool fx(string s)//判断单词的性别
{
	int len=s.size();
	s=" "+s;
	if(s[len]=='s'&&s[len-1]=='o'&&s[len-2]=='i'&&s[len-3]=='l')
		return 1;
	if(s[len]=='r'&&s[len-1]=='t'&&s[len-2]=='e')
		return 1;
	if(s[len]=='s'&&s[len-1]=='i'&&s[len-2]=='t'&&s[len-3]=='i'&&s[len-4]=='n'&&s[len-5]=='i')
		return 1;
	if(s[len]=='a'&&s[len-1]=='l'&&s[len-2]=='a'&&s[len-3]=='i'&&s[len-4]=='l')
		return 0;
	if(s[len]=='a'&&s[len-1]=='r'&&s[len-2]=='t'&&s[len-3]=='e')
		return 0;
	if(s[len]=='s'&&s[len-1]=='e'&&s[len-2]=='t'&&s[len-3]=='i'&&s[len-4]=='n'&&s[len-5]=='i')
		return 0;
}
int fc(string s)//判断单词的词性
{
	int len=s.size();
	s=" "+s;
	if(s[len]=='s'&&s[len-1]=='o'&&s[len-2]=='i'&&s[len-3]=='l')
		return 1;
	if(s[len]=='r'&&s[len-1]=='t'&&s[len-2]=='e')
		return 2;
	if(s[len]=='s'&&s[len-1]=='i'&&s[len-2]=='t'&&s[len-3]=='i'&&s[len-4]=='n'&&s[len-5]=='i')
		return 3;
	if(s[len]=='a'&&s[len-1]=='l'&&s[len-2]=='a'&&s[len-3]=='i'&&s[len-4]=='l')
		return 1;
	if(s[len]=='a'&&s[len-1]=='r'&&s[len-2]=='t'&&s[len-3]=='e')
		return 2;
	if(s[len]=='s'&&s[len-1]=='e'&&s[len-2]=='t'&&s[len-3]=='i'&&s[len-4]=='n'&&s[len-5]=='i')
		return 3;
}
int main()
{
	while(cin>>a[++cnt]);
	cnt--;
	int x=0,y=0;
	for(int i=1;i<=cnt;i++)
	{
		if(!fh(a[i]))//不合法直接输出NO
		{
			cout<<"NO";
			return 0;
		}
		if(fx(a[i]))x++;
		else y++;
	}
	if(!((!x&&y)||(x&&!y)))
	{//性别不一样输出NO
		cout<<"NO";
		return 0;
	}
	int num=0;
	if(cnt==1&&fh(a[1]))
	{
		cout<<"YES";
		return 0;
	}//只有一个合法单词输出YES
	if(cnt==2)
	{//只有两个单词的特殊情况
		if(fc(a[1])==1&&fc(a[2])!=2)
		{//第一个单词是形容词但是第二个单词不是名词
			cout<<"NO";
			return 0;
		}
		if(fc(a[1])==2&&fc(a[2])!=3)
		{//第一个单词是名词但是第二个单词不是动词
			cout<<"NO";
			return 0;
		}
		if(fc(a[1])==3)
		{//第一个单词是动词
			cout<<"NO";
			return 0;
		}
		cout<<"YES";
		return 0;
	}
	for(int i=2;i<cnt;i++)
	{
		if(fc(a[i])==1)
		{//如果当前单词是形容词
			if(fc(a[i-1])==1&&(fc(a[i+1])==1||fc(a[i+1])==2))
				continue;
			cout<<"NO";//如果形容词的上一个不是形容词或者形容词的下一个不是形容词或名词就输出NO
			return 0;
		}
		if(fc(a[i])==2)
		{//如果当前单词是名词
			if(fc(a[i-1])==1&&fc(a[i+1])==3)
				continue;
			cout<<"NO";//如果名词的上一个不是形容词或者名词的下一个不是动词就输出NO
			return 0;
		}
		if(fc(a[i])==3)
		{//如果当前单词是动词
			if((fc(a[i-1])==3||fc(a[i-1])==2)&&fc(a[i+1])==3)
				continue;
			cout<<"NO";//如果动词的上一个不是动词或名词,或者动词的下一个不是动词就输出NO
			return 0;
		}
	}
	for(int i=1;i<=cnt;i++)
		if(fc(a[i])==2)
			num++;//判断有多少个名词
	if(num!=1&&cnt>1)
	{//有多个名词就输出NO
		cout<<"NO";
		return 0;
	}
	cout<<"YES";//改句子符合语法,输出YES
	return 0;
}

完美撒花~

你可能感兴趣的:(算法,c++)