• 洛谷 P1310 表达式的值


    题目传送门

    因为看不懂题解里的做法,只好自己写了一个大模拟+DP.

    对于带括号的式子,从里到外一层一层的处理括号,将其转化为一个数(即括号内可获得的方案数),这样做可以保证我们每次处理的都是一个不带括号的式子,只需考虑算式优先级即可,先算(*),然后将(*)的结果转化成数字,重新构成一个只含+的式子.

    思维上比较简单,难度主要在于代码,需要考虑怎样一层层向里和向外处理括号的许多细节,还需要考虑最外面一层状态转移的多种情况,和处理完(*)后,转化只含+的式子的多种情况.

    带调试版代码

    #include<iostream>
    #include<cstdio>
    #include<map>
    #include<cstring>
    #define mod 10007
    
    using namespace std;
    
    int n,num = 1,p,sum,pp,ans[200001][2],fh[200001],_num = 1;
    int f_ans[200001][2];
    bool vis[200001],flag;
    string l,l1;
    struct kkk {
    	int _1,_0;
    };
    
    inline kkk maxin(int deep,bool len) {
    	int tot = 0,oo = 0,_tot = 0;;
    	bool maxx = 0;
    	map<int ,map<int ,int> > f,f_f;
    	map<int ,bool> mx,fl;
    	for(p;p < sum; p++) {
    		if(deep != 1) {
    			maxx = 0;
    			if(l[p] == ')') break;;
    			if(l[p] == '_' && l[p-1] == '+') {
    				f[++tot][1] = 1;
    				f[tot][0] = 1;
    				maxx = 1;
    			}
    			if(l[p-1] == '*' && l[p] == '_') {
    				f[++tot][1] = 1;
    				f[tot][0] = 1;
    				maxx = 1;
    			}
    			if(l[p-1] == '*') mx[++_tot] = 1;
    			if(l[p-1] == '+') mx[++_tot] = 0;
    			if(l[p] == '(') {
    				p++;
    				kkk u = maxin(deep + 1,1);
    				f[++tot][1] = u._1;
    				f[tot][0] = u._0;
    				continue;
    			}
    			if(l[p-1] == '(' && l[p] == '_') {
    				f[++tot][1] = 1;
    				f[tot][0] = 1;
    			}
    		}
    		else {
    			maxx = 0;
    			if(l[p] == ')') break;
    			if(l[p-1] == '+' && l[p] == '_') {
    				ans[++num][1] = 1;
    				ans[num][0] = 1;
    				maxx = 1;
    			}
    			if(l[p-1] == '*' && l[p] == '_') {
    				ans[++num][1] = 1;
    				ans[num][0] = 1;
    				maxx = 1;
    			}
    			if(l[p-1] == '*') fh[++_num] = 1;
    			if(l[p-1] == '+') fh[++_num] = 0;
    			if(l[p] == '_' && p == 0) {
    				ans[num][1] = 1;
    				ans[num][0] = 1;
    				flag = 1;
    			}
    			if(l[p] == '(') {
    				p++;
    				kkk u;
    				u = maxin(deep + 1,1);
    				ans[++num][1] = u._1;
    				ans[num][0] = u._0;
    				continue;
    			}
    		}
    	}
    	if(deep != 1) {
    		for(int i = 1;i <= _tot; i++)
    			if(mx[i] == 1) {
    				f[i+1][0] = f[i][1] % mod * f[i+1][0] % mod + f[i][0] % mod * f[i+1][0] % mod + f[i+1][1] % mod * f[i][0] % mod;
    				f[i+1][1] = f[i][1] % mod * f[i+1][1] % mod;	
    				fl[i] = 1;
    			}
    		for(int i = 1;i <= tot; i++)
    			if(!fl[i])
    				f_f[++oo][0] = f[i][0] % mod,f_f[oo][1] = f[i][1] % mod;
    		for(int i = 2;i <= oo; i++) {			
    			f_f[i][1] = f_f[i][0] % mod * f_f[i-1][1] % mod + f_f[i][1] % mod * f_f[i-1][0] % mod + f_f[i][1] % mod * f_f[i-1][1] % mod;
    			f_f[i][0] = f_f[i-1][0] % mod * f_f[i][0] % mod;
    		}
    	}
    	kkk o;
    	o._0 = f_f[oo][0] % mod;
    	o._1 = f_f[oo][1] % mod;
    	return o;
    }
    
    int main() {
    	scanf("%d",&n);
    	cin >> l1;
    	for(int i = 0;i < n; i++) {
    		if(l1[i] == '(') {
    			l = l + l1[i];
    			continue;
    		}
    		if(l1[i] == '+' || l1[i] == '*') {
    			if(i == 0 || l1[i-1] != ')') {
    				l = l + '_' + l1[i];
    				continue;
    			}
    			l = l + l1[i];
    		}
    		if(l1[i] == ')' && l1[i-1] != ')') {
    			l = l + '_' + l1[i];
    			continue;
    		}
    		if(l1[i] == ')')
    			l = l + ')';
    	}
    	sum = l.length();
    	if(l[sum-1] != ')') l = l + '_';
    	sum = l.length();
    	maxin(1,0);
    	bool lm = 0;
    	for(int i = 2;i <= _num; i++) {
    		if(fh[i] == 1 && !flag) {
    			ans[i+1][0] = ans[i][1] % mod * ans[i+1][0] % mod + ans[i][0] % mod * ans[i+1][0] % mod + ans[i+1][1] % mod * ans[i][0] % mod;
    			ans[i+1][1] = ans[i][1] % mod * ans[i+1][1] % mod;
    			vis[i] = 1;
    		}
    		if(fh[i] == 1 && flag) {
    			ans[i][0] = ans[i-1][1] % mod * ans[i][0] % mod + ans[i-1][0] % mod * ans[i][0] % mod + ans[i][1] % mod * ans[i-1][0] % mod;
    			ans[i][1] = ans[i-1][1] % mod * ans[i][1] % mod;
    			vis[i-1] = 1;
    			lm = 1;
    		}
    	}
    	sum = 0;
    		for(int i = 2;i <= num; i++)
    			if(!vis[i])
    				f_ans[++sum][0] = ans[i][0] % mod,f_ans[sum][1] = ans[i][1] % mod;
    	for(int i = 2;i <= sum; i++) {			
    		f_ans[i][1] = f_ans[i][0] % mod * f_ans[i-1][1] % mod + f_ans[i][1] % mod * f_ans[i-1][0] % mod + f_ans[i][1] % mod * f_ans[i-1][1] % mod;
    		f_ans[i][0] = f_ans[i-1][0] % mod * f_ans[i][0] % mod;
    	}
    	printf("%d ",f_ans[sum][0] % mod);
    	return 0;
    }
  • 相关阅读:
    [leetcode]Merge Intervals
    ffmpeg错误隐藏框架分析
    [置顶] Hash查找,散列查找
    VS2008LINK : fatal error LNK1000: Internal error during IncrBuildImage
    HDU1257:最少拦截系统(LIS)
    ubuntu系统使用dnw下载程序
    ubuntu系统使用minicom终端操作说明
    uboot显示logo的方式
    在XC2440的uboot中挂载U盘,利用FAT文件系统读写U盘文件
    不知道黑片,千万别说你懂“U盘”-解读Nand Flash
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/13817652.html
Copyright © 2020-2023  润新知