noip的等价表达式

 

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
const int q[5]={1,2,3,4,5};
const int inf=0x3f3f3f3f;
string s,ch;
int n,ans[5];
int number(string &s)
{
	int ans=0,len=s.length();
	for (int i=0;i<len;i++) ans=ans*10+s[i]-'0';
	return ans;
}
int pow(int a,int b)
{
	int ans=1;
	for (int i=1;i<=b;i++) ans=ans*a;
	return ans;
}

int opt(string &s)
{
	int len=s.length(),num=0;
	bool b[4];
	b[0]=b[1]=b[2]=false;b[3]=true;
	for (int i=0;i<len;i++) 
	{
		if (s[i]=='(') num++;if (s[i]==')') num--;if (num) continue;
		if (s[i]=='+'||s[i]=='-') b[0]=true;
		if (s[i]=='*') b[1]=true;
		if (s[i]=='^') b[2]=true;
	}
	for (int i=0;i<=3;i++) if (b[i]) return i;
}

int pan(string s,int a)
{
	int len=s.length();if (len==0) return 0;
	int tt=1,ans,last=0,num=0,op=opt(s);
	if (op==0)
	{
		ans=0;
		for (int i=0;i<len;i++)
		{
			if (s[i]=='(') num++;if (s[i]==')') num--;if (num) continue;
			if (s[i]!='+'&&s[i]!='-') continue;
			
			ans=ans+tt*pan(s.substr(last,i-last),a);
			tt= s[i]=='+' ? 1:-1;
			last=i+1;
		}
		ans=ans+tt*pan(s.substr(last,len-last),a);
		return ans;
	}
	
	if (op==1)
	{
		ans=1;
		for (int i=0;i<len;i++)
		{
			if (s[i]=='(') num++;if (s[i]==')') num--;if (num) continue;
			if (s[i]!='*') continue;
			
			ans=ans*pan(s.substr(last,i-last),a);
			last=i+1;
		} 
		ans=ans*pan(s.substr(last,len-last),a);
		return ans;
	}
	
	if (op==2) 
	{
		ans=-1;
		for (int i=0;i<len;i++)
		{
			if (s[i]=='(') num++;if (s[i]==')') num--;if (num) continue;
			if (s[i]!='^') continue;
			
			if (ans==-1) ans=pan(s.substr(last,i-last),a);
			else ans=pow(ans,pan(s.substr(last,i-last),a));
			last=i+1;
		}
		ans=pow(ans,pan(s.substr(last,len-last),a));
		return ans;
	}
	if (s[0]=='(') return pan(s.substr(1,len-2),a);
	if (s[0]=='a') return a;
	return number(s);
}

void read(string &s)
{
	string y;getline(cin,y);
	int len=y.length();s.clear();
	for (int i=0;i<len;i++) if (y[i]!=' ') s.push_back(y[i]);
}

void debug()
{
	int tmp;
	read(s);
	cin>>tmp;getchar();
	int ans=pan(s,tmp);
	printf("%d\n",ans);
	
}


int main()
{
	//debug();
	
	read(s);
	for (int i=0;i<5;i++) ans[i]=pan(s,q[i]);
	cin>>n;getchar();
	bool o;
	for (int i=0;i<n;i++)
	{
		read(ch);
		o=true;
		for (int j=0;j<5;j++) if (pan(ch,q[j])!=ans[j]) o=false;
		if (o) printf("%c",65+i);
	}
	return 0;
}

/*
(a+1)^2
20
a*a+2*a+1
a^2+2*a+2-1-1+1
*/





 

总结

1:对于这种字符串题,递归处理是一种好的方法

2:对于这些对时间复杂度要求不是特别高但是,考验代码实现技巧的这一类字符串题,可以通过string类型来简化我们的程序

3:string一系列函数待填坑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值