表达式

1.P1739 表达式括号匹配

题目:https://www.luogu.com.cn/problem/P1739

 

代码:

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
string s;stack<char>sta;
int main(){
	cin>>s;
	for(int i=0;i<s.length();i++){
		if(s[i]=='(')sta.push(s[i]);
		else if(s[i]==')'){
			if(sta.size())sta.pop();
			else{
				cout<<"NO";
				return 0;
			}
		}
	}
	cout<<(sta.size()?"NO":"YES");
	return 0;
}

  

解题思路:

建立一个栈,遇到左括号就弹出一个右括号,如果没有右括号即输出NO,在最后判断是否还有左括号,输出YES或NO

注意事项:

1.当没有左括号时应直接输出NO,否则会RE

 

 

2.P1449后缀表达式

题目:https://www.luogu.com.cn/problem/P1449

代码:

#include<bits/stdc++.h>
using namespace std;
int cal(int a,int b,char c){
	switch(c){
		case '+':return a+b;break;
		case '-':return a-b;break;
		case '*':return a*b;break;
		case '/':return a/b;break;
	}
}
stack<int>sta;
string s;
int v=-1;
int main(){
	cin>>s;
	for(int i=0;i<s.length();i++){
		if(s[i]>='0'&&s[i]<='9'){
			v=0;
			while(s[i]>='0'&&s[i]<='9')v=v*10+(s[i++]-'0');
		}
		if(s[i]=='.'){
			sta.push(v);
			v=-1;
		}
		if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'){
			int x,y;
			x=sta.top();sta.pop();
			y=sta.top();sta.pop();
			sta.push(cal(y,x,s[i]));
		}
	}
	cout<<sta.top();
	return 0;
}

  

解题思路:

按题意模拟即可

3.P1981 [NOIP2013 普及组] 表达式求值

题目:https://www.luogu.com.cn/problem/P1981

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 1e4;
ll a,sum=0;char b;stack<ll>sta;
int main(){
	cin>>a;sta.push(a%mod);
	while(cin>>b>>a){
		if(b=='+')sta.push(a);
		else sta.top()=(sta.top()*a%mod);
	}
	while(sta.size())sum=(sta.top()+sum)%mod,sta.pop();
	cout<<sum%mod;
	return 0;
}

  

解题思路:
按题意模拟即可

注意事项:

1.需要在求和过程中取余

 

4.P1175 表达式的转换

题目:https://www.luogu.com.cn/problem/P1175

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
map<char,int>yx;
string mids,nexs;int len;
int cal(int a,int b,int c){
	switch(c){
		case '+':return a+b;break;
		case '-':return a-b;break;
		case '*':return a*b;break;
		case '/':return a/b;break; 
		case '^':
//			return (int)(pow(a,b));break;
			int ans=1;
			for(int i=1;i<=b;i++)ans*=a;
			return ans;
			break;
	}
}
string midtoNex(string s){
	stack<char>op;
	string s2="";
	int len=s.length();
	for(int i=0;i<len;i++){
		if(s[i]=='(')op.push(s[i]);
		else if(s[i]==')'){
			while(op.top()!='('){
				s2+=op.top();
				s2+=" ";
				op.pop();
			}
			op.pop();
		}else if(s[i]>='0'&&s[i]<='9'){
			s2+=s[i];
			s2+=" ";
		}else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'||s[i]=='^'){
			if(s[i]!='^'){
				while(op.size()&&yx[op.top()]>=yx[s[i]]){
					s2+=op.top();
					s2+=" ";
					op.pop();
				}
				op.push(s[i]);
			}else{
				op.push(s[i]);
			}
		}
	}
	while(op.size()){
		s2+=op.top();
		s2+=" ";
		op.pop();
	}
	return s2;
}
void print(stack<int>st){
	if(st.empty())return;
	int a=st.top();
	if(st.size()){
		st.pop();
		print(st);
	}
	cout<<a<<' ';
}
void Solve(string k){
	stack<int>st;
	int len=k.length();
	for(int i=0;i<len;i++){
		if(k[i]>='0'&&k[i]<='9')st.push(k[i]-'0');
		else if(k[i]!=' '){
			int y=st.top();st.pop();
			int x=st.top();st.pop();
			st.push(cal(x,y,k[i]));
			print(st);
			cout<<k.substr(i+2,len-i-1)<<'\n';
		}
	}
}
int main(){
	yx['^']=3;
	yx['*']=yx['/']=2;
	yx['+']=yx['-']=1;
	yx['(']=0;
	cin>>mids;len=mids.length();
	nexs=midtoNex(mids);
	cout<<nexs<<'\n';
	Solve(nexs);
	return 0;
}

  

解题思路:

遇到数字直接加入后缀串,遇到^和数字一样,遇到其他运算符,放到相应位置,模拟即可

注意事项:

1.运算符的优先级

2.^运算

 

5.P7073 [CSP-J2020] 表达式

题目:https://www.luogu.com.cn/problem/P7073

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6+255;
struct node{
	bool v;int l,r;char op;
}tree[N*4];
int flag[N],n,q,cnt=0;string s;
void init(){
	getline(cin,s);s+=" ";
	cin>>n;cnt=n;
	for(int i=1;i<=n;i++){
		cin>>tree[i].v;
		tree[i].l=tree[i].r=0;
		tree[i].op='#';
	}
}
void build(){
	stack<int>num;int t=-1,num1,num2;int len=s.length();
	for(int i=0;i<len;i++){
		if(s[i]=='x')t=0;
		else if(s[i]>='0'&&s[i]<='9')t=t*10+(s[i]-'0');
		else if(s[i]==' '){
			if(t!=-1){
				num.push(t);
				t=-1;
			}
		}else if(s[i]=='!'){
			num1=num.top();num.pop();
			tree[++cnt].op='!';
			tree[cnt].l=num1;tree[cnt].r=0;
			tree[cnt].v=!tree[num1].v;
			num.push(cnt);
		}else if(s[i]=='&'){
			num2=num.top();num.pop();
			num1=num.top();num.pop();
			tree[++cnt].op='&';
			tree[cnt].l=num1;tree[cnt].r=num2;
			tree[cnt].v=tree[num1].v&tree[num2].v;
			num.push(cnt);
		}else if(s[i]=='|'){
			num2=num.top();num.pop();
			num1=num.top();num.pop();
			tree[++cnt].op='|';
			tree[cnt].l=num1;tree[cnt].r=num2;
			tree[cnt].v=tree[num1].v|tree[num2].v;
			num.push(cnt);
		}
	}
}
void dfs(int root){
	flag[root]=1;
	if(tree[root].op=='#')return;
	if(tree[root].op=='!')dfs(tree[root].l);
	if(tree[root].op=='&'){
		if(tree[root].v==0){
			if(tree[tree[root].l].v==1)dfs(tree[root].r);
			if(tree[tree[root].r].v==1)dfs(tree[root].l);
		}else{
			dfs(tree[root].l);
			dfs(tree[root].r);
		}
	}
	if(tree[root].op=='|'){
		if(tree[root].v==1){
			if(tree[tree[root].l].v==0)dfs(tree[root].r);
			if(tree[tree[root].r].v==0)dfs(tree[root].l);
		}else{
			dfs(tree[root].l);
			dfs(tree[root].r);
		}
	}
}
int main(){
	init();build();dfs(cnt);
	cin>>q;
	while(q--){
		int x;cin>>x;
		if(flag[x])cout<<!tree[cnt].v<<'\n';
		else cout<<tree[cnt].v<<'\n';
	}
	return 0;
}

  

解题思路:

按题意,建好表达式树,进行深搜,遍历节点,打标记,输出答案即可

 

6.P1310 [NOIP2011 普及组] 表达式的值

题目:https://www.luogu.com.cn/problem/P1310

 

代码:

#include<bits/stdc++.h>
using namespace std;
const int MOD = 1e4+7;
stack<vector<int>> st;stack<char>op;
map<char,int>yx;
int n;string s;
void calc(){
	vector<int>a=st.top();st.pop();
	vector<int>b=st.top();st.pop();
	char c=op.top();op.pop();
	vector<int>ans(2);
	if(c=='*'){
		ans[0]=(a[0]*b[0]+a[0]*b[1]+a[1]*b[0])%MOD;
		ans[1]=(a[1]*b[1])%MOD;
	}else{
		ans[0]=(a[0]*b[0])%MOD;
		ans[1]=(a[0]*b[1]+a[1]*b[0]+a[1]*b[1])%MOD;
	}
	st.push(ans);
}
int main(){
	yx['(']=0;yx['+']=1;yx['*']=2;
	cin>>n>>s;
	st.push({1,1});
	for(int i=0;i<n;i++){
		char c=s[i];
		if(c=='(')op.push(c);
		else if(c==')'){
			while(op.top()!='(')calc();
			op.pop();
		}else{
			while(op.size()&&yx[op.top()]>=yx[c])calc();
			st.push({1,1});
			op.push(c);
		}
	}
	while(op.size())calc();
	cout<<st.top()[0]%MOD;
	return 0;
}

  

解题思路:

这两种符号分别对应与运算和或运算,按照规则进行dp,最终栈顶的结果即为答案

 

7.P8815 [CSP-J 2022] 逻辑表达式

题目:https://www.luogu.com.cn/problem/P8815

 

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6+255;
char s[N];
struct node{
	char num;
	int l,r;
	node(){};
	node(char s){num=s;}
	node(char s,int ls,int rs){num=s,l=ls,r=rs;}
}tree[4*N];
map<char,int>yx;
stack<int>num;
stack<char>op;
int n,ans,cnt,cnt1,cnt2;
void create(){
	int y=num.top();num.pop();
	int x=num.top();num.pop();
	tree[++cnt]=node(op.top(),x,y);
	op.pop();
	num.push(cnt);
}
void build(){
	int n=strlen(s);
	for(int i=0;i<n;i++){
		if(s[i]=='(')op.push(s[i]);
		else if(s[i]==')'){
			while(op.top()!='(')create();
			op.pop();
		}else if(s[i]=='&'||s[i]=='|'){
			while(op.size()&&yx[op.top()]>=yx[s[i]])create();
			op.push(s[i]);
		}else{
			tree[++cnt]=node(s[i]);
			num.push(cnt);
		}
	}
	while(op.size())create();
}
int dfs(int root){
	if(tree[root].num=='0')return 0;
	if(tree[root].num=='1')return 1;
	if(tree[root].num=='&'){
		if(dfs(tree[root].l)==0){
			cnt1++;
			return 0;
		}
		return dfs(tree[root].r);
	}
	if(dfs(tree[root].l)==1){
		cnt2++;
		return 1;
	}
	return dfs(tree[root].r);
}
int main(){
	yx['(']=0;yx['|']=1;yx['&']=2;
	cin>>s;
	build();
	int ans=dfs(cnt);
	cout<<ans<<'\n'<<cnt1<<' '<<cnt2;
	return 0;
}

  

解题思路:

与2020年的表达式思路一样,先建好表达式树,再进行深搜,统计答案,最后输出答案

posted @ 2023-05-20 17:36  天雷小兔  阅读(98)  评论(0)    收藏  举报