明明进了中学之后,学到了代数表达式。有一天,他碰到一个很麻烦的选择题。这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。假设你是明明,能完成这个任务吗?这个选择题中的每个表达式都满足下面的性质:1. 表达式只可能包含一个变量‘a’。2. 表达式中出现的数都是正整数,而且都小于10000。3. 表达式中可以包括四种运算‘+’(加),‘-’(减),‘*’(乘),‘^’(乘幂),以及小括号‘(’,‘)’。小括号的优先级最高,其次是‘^’,然后是‘*’,最后是‘+’和‘-’。‘+’和‘-’的优先级是相同的。相同优先级的运算从左到右进行。(注意:运算符‘+’,‘-’,‘*’,‘^’以及小括号‘(’,‘)’都是英文字符)4.
幂指数只可能是1到10之间的正整数(包括1和10)。5. 表达式内部,头部或者尾部都可能有一些多余的空格。下面是一些合理的表达式的例子:((a^1) ^ 2)^3,a*a+a-a,((a+a)),9999+(a-a)*a,1 + (a -1)^3,1^10^9……对于30%的数据,表达式中只可能出现两种运算符‘+’和‘-’;对于其它的数据,四种运算符‘+’,‘-’,‘*’,‘^’在表达式中都可能出现。对于全部的数据,表达式中都可能出现小括号‘(’和‘)’。分析:


1.不需要考虑括号不匹配问题,输入绝对合法。
2.不需要考虑形如
    (-3+a^7)*2
  这样的情况。

3.另一方面,我认为只有试够11个数才能充分说明正确性:因为

a^10+k9a^9+k8a^8+.......=(a+3)^10+......

这是一个一元十次方程,它需要11个点来确定一条十次曲线。所以要将0-10都代入才能说明问题。

当然,如果这是一条6次曲线,7个点就够,可是谁有想写一个判断次数的函数呢?

4.因为取余运算,导致运算顺序不同,结果就不同。这是一个神坑。所以试的点少一点	,取余数大一点就容易过。



#include<iostream>
using namespace std;
#define big 10007
#define test 8
char ti[51];//题干
int size;//选项个数
int result[test];//准备试的数
bool prior(char a, char b){//运算符a优先级是否大于b
	if (a == '^')return true;
	if (b == '^')return false;
	if (a == '*')return true;
	if (b == '*')return false;
	return true;
}
int power(int a, int b){//乘幂函数要取余
	int i;
	int ans = 1;
	for (i = 0; i < b; i++){
		ans *= a;
		ans %= big;
	}
	return ans;
}
int op(int a, int b, char o){
	switch (o){
	case '^':return power(a, b);
	case '*':a *= b; a %= big; return a;
	case '+':return (a + b) % big;
	case '-':return (a - b) % big;
	}
}
//x表示数字,o表示符号
int calculate(int x[], int xsize, char o[], int osize){
	int i;
	int xstack[51];
	int xtop = 0;
	char ostack[51];
	int otop = 0;
	int xi, oi;
	xi = oi = 0;
	xstack[xtop++] = x[xi++];
	while (xi<xsize&&oi<osize){
		while (otop != 0 && prior(ostack[otop - 1], o[oi])){
			xstack[xtop - 2] = op(xstack[xtop - 2], xstack[xtop - 1], ostack[otop - 1]);
			xtop--;
			otop--;
		}
		ostack[otop++] = o[oi++];
		xstack[xtop++] = x[xi++];
	}
	while (otop >0){
		xstack[xtop - 2] = op(xstack[xtop - 2], xstack[xtop - 1], ostack[otop - 1]);
		xtop--;
		otop--;
	}
	return xstack[0];
}
int go(char ex[], int a){
	int i, j;
	int x[51];
	int xi = 0;
	char o[51];
	int oi = 0;
	i = 0;
	while (ex[i]){
		while (ex[i] == ' ')i++;
		if (ex[i] == 0)break;
		if (ex[i] == '('){
			int left = 1;
			char temp[51];
			j = 0;
			i++;
			while (true){
				temp[j] = ex[i];
				if (temp[j] == '(')left++;
				else if (temp[j] == ')')left--;
				if (left == 0){
					temp[j] = 0;
					x[xi++] = go(temp, a);
					i++;
					break;
				}
				i++; j++;
			}
		}
		else if (ex[i] == 'a'){
			x[xi++] = a;
			i++;
		}
		else{
			int n = 0;
			while (ex[i] >= '0'&&ex[i] <= '9'){
				n *= 10;
				n += ex[i] - '0';
				i++;
			}
			x[xi++] = n;
		}
		while (ex[i] == ' ')i++;
		if (ex[i] == 0)break;
		if (ex[i] == '+' || ex[i] == '-' || ex[i] == '*' || ex[i] == '^'){
			o[oi++] = ex[i];
		}
		i++;
	}
	return calculate(x, xi, o, oi);
}
int main(){
	freopen("in.txt", "r", stdin);
	cin.getline(ti, sizeof(ti));
	cin >> size;
	int i;
	for (i = 0; i < test; i++)
	{
		result[i] = go(ti, i);
	}
	char choose[51];
	cin.getline(choose, 55);
	for (i = 0; i < size; i++){
		cin.getline(choose, 55);
		int j;
		int ans;
		for (j = 0; j < test; j++){
			ans = go(choose, j);
			if (ans != result[j])break;
		}
		if (j == test){
			cout << (char)(i + 'A');
		}
	}
	return 0;
}

vijos-1003等价表达式的更多相关文章

  1. Vijos P1003 等价表达式 随机数+单调栈

    题目链接:https://vijos.org/p/1003 题意: 1. 表达式只可能包含一个变量‘a’. 2. 表达式中出现的数都是正整数,而且都小于10000. 3. 表达式中可以包括四种运算‘+ ...

  2. 数据结构--栈 codevs 1107 等价表达式

    codevs 1107 等价表达式 2005年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Descripti ...

  3. 等价表达式(noip2005)

    3.等价表达式 [问题描述]    兵兵班的同学都喜欢数学这一科目,中秋聚会这天,数学课代表给大家出了个有关代数表达式的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也 ...

  4. 洛谷 P1054 等价表达式 解题报告

    P1054 等价表达式 题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的 ...

  5. 洛谷P1054 等价表达式

    P1054 等价表达式 题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的 ...

  6. 等价表达式 2005年NOIP全国联赛提高组(栈模拟)

    P1054 等价表达式 题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的 ...

  7. 洛谷 P1054 等价表达式

    洛谷 P1054 等价表达式 题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式, ...

  8. 表达式求值(noip2015等价表达式)

    题目大意 给一个含字母a的表达式,求n个选项中表达式跟一开始那个等价的有哪些 做法 模拟一个多项式显然难以实现那么我们高兴的找一些素数代入表达式,再随便找一个素数做模表达式求值优先级表 - ( ) + ...

  9. NOIP2005 等价表达式

    题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数 ...

随机推荐

  1. keil 怎样新建工程,编写代码?

    打开keil uversion 4 新建工程 新建的工程名字,点击保存. 选择 cpu 单片机芯片 Atmel ----> AT89C51 不用将汇编代码加入工程,选择 “否” 新建文件,注意这 ...

  2. CDN下nginx获取用户真实IP地址

    随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户 ...

  3. PCA原理与实践

    在对数据进行预处理时,我们经常会遇到数据的维数非常之大,如果不进行相应的特征处理,那么算法的资源开销会很大,这在很多场景下是我们不能接受的.而对于数据的若干维度之间往往会存在较大的相关性,如果能将数据 ...

  4. Appium学习实践(三)测试用例脚本以及测试报告输出

    之前Appium学习实践(二)Python简单脚本以及元素的属性设置中的脚本,会有一个问题,就是在每个测试用例完成之后都会执行tearDown,然后重新setUp,这样导致脚本的执行效率偏低,而且会有 ...

  5. 第8章 用户模式下的线程同步(4)_条件变量(Condition Variable)

    8.6 条件变量(Condition Variables)——可利用临界区或SRWLock锁来实现 8.6.1 条件变量的使用 (1)条件变量机制就是为了简化 “生产者-消费者”问题而设计的一种线程同 ...

  6. Vector3 *2 ,ToString()自动四舍五入

    还以为出错了,仔细看发现ToString()自动四舍五入 Vector3 forward = Camera.main.transform.forward; Debug.Log("forwar ...

  7. python反弹tty shell

    linux环境下进行内外渗透需要反弹shell连接内网ssh,Telnet等,就需要tty层的shell了.python代码转过来的,备用. #!/usr/bin/python import sys ...

  8. java问题小总结

    1.在使用equals的时候,把  "".equals(name);放在左边 如果右边的没有初始化,可以避免出错. 2.对于 ObjectId id; 在mongodb里面对其进行 ...

  9. 线程 VS 进程

    线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间; (2)资源拥有: ...

  10. MySQL迁移[转]

    http://dbarobin.com/2015/09/15/migration-of-mysql-on-different-scenes/ MySQL 迁移方案概览 MySQL 迁移无非是围绕着数据 ...