表达式
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年的表达式思路一样,先建好表达式树,再进行深搜,统计答案,最后输出答案

浙公网安备 33010602011771号