zoukankan      html  css  js  c++  java
  • 【NOIP2005提高组T4】等价表达式+模拟+栈

    测试地址:等价表达式

    做法:这个题目我首先想到的方法是,展开表达式,存储未知数a的各个次幂的系数,展开每个表达式后再进行对比。但这样子很难处理,于是就想到把一些较大的质数代入表达式求解,然后比较,多代入几个质数,如果结果都相同,那么两个表达式就基本上等价了。至于表达式的计算,用栈的方法模拟即可。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <stack>
    #define mod 100000007
    using namespace std;
    int n,p[6]={0,1187,1291,1523,1759,1933}; //要代入的大质数
    int len,pos[210],pi;
    long long ans[6],val[6];
    char s[210],a[210];
    
    void read() //读入表达式,并手动把其中的空格去掉,以便后面的操作
    {
      gets(s);
      int slen=strlen(s);
      len=0;
      for(int i=0;i<slen;i++)
        if (s[i]!=' ') a[++len]=s[i];
    }
    
    long long power(long long x,int y) //快速幂求x^y(不用应该也可以...一开始没看到幂指数≤10这个条件)
    {
      long long s=1,tmp=x;
      while(y!=0)
      {
        if (y&1) s=(s*tmp)%mod;
        tmp=(tmp*tmp)%mod;y>>=1;
      }
      return s%mod;
    }
    
    long long number(int l,int r) //计算字符串中[l,r]一段代表的数字
    {
      long long s=0;
      for(int i=l;i<=r;i++)
        s=(s*10+a[i]-'0')%mod;
      return s%mod;
    }
    
    long long work(int l,int r) //求表达式的值
    {
      int i;
      for(i=r;i>=l;i--)
      {
        if (a[i]==')') i=pos[i];
    	else if (a[i]=='+'||a[i]=='-') break;
      }
      if (i>=l)
      {
        long long x,y;
    	x=(work(l,i-1)+mod)%mod;
    	y=(work(i+1,r)+mod)%mod;
    	if (a[i]=='+') return (x+y)%mod;
    	else return (x-y+mod)%mod;
      }
      for(i=r;i>=l;i--)
      {
        if (a[i]==')') i=pos[i];
    	else if (a[i]=='*') break;
      }
      if (i>=l)
      {
        long long x,y;
    	x=(work(l,i-1)+mod)%mod;
    	y=(work(i+1,r)+mod)%mod;
    	return (x*y)%mod;
      }
      for(i=r;i>=l;i--)
      {
        if (a[i]==')') i=pos[i];
    	else if (a[i]=='^') break;
      }
      if (i>=l)
      {
        long long x,y;
    	x=(work(l,i-1)+mod)%mod;
    	y=(work(i+1,r)+mod)%mod;
    	return power(x,y)%mod;
      }
      if (a[r]==')') return work(l+1,r-1);
      if (a[r]=='a') return p[pi];
      return number(l,r);
    }
    
    void calc(bool mode)
    {
      stack<int> b;
      for(int i=len;i>=1;i--)
      {
        if (a[i]==')') b.push(i);
    	if (a[i]=='(')
    	{
    	  pos[b.top()]=i;
    	  b.pop();
    	}
      }
      for(pi=1;pi<=5;pi++)
      {
        long long value=(work(1,len)+mod)%mod;
    	if (!mode) ans[pi]=value;
    	else val[pi]=value;
      }
    }
    
    int main()
    {
      read();
      calc(0);
      
      scanf("%d",&n);getchar();
      for(int i=0;i<n;i++)
      {
        read();
    	calc(1);
    	int j;
    	for(j=1;j<=5;j++)
    	  if (val[j]!=ans[j]) break;
    	if (j>5) printf("%c",'A'+i);
      }
      
      return 0;
    }
    


  • 相关阅读:
    10.浮动样式
    09.圆角样式及渐变色样式
    08.背景样式
    Oracle中dual表的用途介绍
    PL/SQL包
    Oracle表数据和表结构对比
    oracle如何判断某张表是否存在
    awk编程基础
    Oracle左连接、右连接、全外连接以及(+)号用法
    SpringMVC的三种处理器适配器
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793883.html
Copyright © 2011-2022 走看看