373-时间复杂度(表达式求值)

题目链接:373-时间复杂度

在 ACM 里面,计算复杂度是一项非常重要的事情,常见的复杂度格式有三种:

O(n)
O(lg(n))
O(sqrt(n))
一个算法往往有多种解法,每种解法的复杂度有上述常见的的复杂度组合成,例如排序的两种算法:

快速排序: 时间复杂度为 O(n*lg(n))

冒泡排序: 时间复杂度为 O(n*n)

现在给定你一个 n , m 个算法复杂度,请确定这些复杂度是否会超时。若复杂度计算结果大于 100000000 ,则为超时 (TLE) ,否则输出计算的复杂度,输出的结果保留两位小数。

( lg(n) 表示以 2 为底数, n 为真数的值 )

输入描述:
第一行输入n (1≤n≤10000), m(1≤m≤100), 其中n为题目描述的数,m为算法复杂度的个数。 接下来m行,每行为一个串,每个串都包含O()任何括号里面的数据保证仅由n,lg(),sqrt(),*组成并且合法。如sample input所示。

输出描述:
对于每个串,若计算出来的复杂度大于100000000,则输出TLE,否则输出该复杂度的计算次数

样例输入:
复制
10000 6
O(n*n)
O(n*n*n)
O(sqrt(n))
O(lg(n))
O(n*lg(n))
O(n*lg(n*lg(n)))

样例输出:
100000000.00
TLE
100.00
13.29
132877.12
170197.33

提示:
关于lg(n)的C语言代码可以这样写 log(n) / log(2)

这里给出三种写法:

第一种是模拟暴力:

#include
#include
#include
#include
using namespace std;
const int maxn=1000000;
char a[maxn];

double n;
int t;
double dfs(int l,int r)
{
    double ans=1;
    for(int i=l; i<=r; i++)
    {
        if(a[i]=='n')
            ans*=n;
        else if(a[i]=='l')
        {
            i+=3;
            int e,f1=1;
            for(int j=i; f1; j++)
            {
                if(a[j]==')')
                    f1--;
                if(a[j]=='(')
                    f1++;
                if(f1==0)
                {
                    e=j;
                    break;
                }
            }
            double f=dfs(i,e-1);//递归
            ans*=log(f)/log(2.0);
            i=e;
        }
        else if(a[i]=='s')
        {
            i+=5;
            int e,f1=1;
            for(int j=i; f1; j++)
            {
                if(a[j]==')')
                    f1--;
                if(a[j]=='(')
                    f1++;
                if(f1==0)
                {
                    e=j;
                    break;
                }
            }
            double f=dfs(i,e-1);//递归
            ans*=sqrt(f);
            i=e;
        }
    }
    return ans;
}
int main()
{
    int g;
    while(~scanf("%lf%d",&n,&t))
    {
        while(t--)
        {
            scanf("%s",a);
            int la=strlen(a);
            double f=dfs(2,la-2);//一直递归括号里的东西
            if(f>100000000.0)
                printf("TLE\n");
            else printf("%.2lf\n",f);
        }
    }
    return 0;
}

第二种是用python写的:

import math

def lg(n):
    return math.log2(n)
def sqrt(n):
    return math.sqrt(n)
def O(n):
    return eval(str(n))
n,m=map(int,input().split())
for case in range(m):
    s=input()
    ans=eval(str(s))
    if ans>100000000:
        print('TLE')
    else:
        print('%.2f' % ans)

第三种是模拟:

#include 
#include 
#include 
#include 
#include 
using namespace std;
int n,m;
string s;
string sta_c[10000];
double num[10000];
int top_c,top_n,len;
int main()
{
    scanf("%d%d",&n,&m);
    while(m--)
    {
        memset(num,0,sizeof(num));
        top_c=top_n=0;
        cin>>s;
        len=s.size();
        for(int i=0; i<=len; i++)
            sta_c[i]="";
        for(int i=2; i1; i++)
        {
            if(s[i]=='n')
                num[++top_n]=n;
            else if(s[i]=='(') sta_c[++top_c]="(";
            else if(s[i]=='l') sta_c[++top_c]="lg";
            else if(s[i]=='s') sta_c[++top_c]="sqrt";
            else if(s[i]=='*') sta_c[++top_c]="*";
            else if(s[i]==')')
            {
                while(sta_c[top_c]!="(")
                {
                    if(sta_c[top_c]=="*")
                    {
                        num[top_n-1]=num[top_n]*num[top_n-1];
                        top_n--;
                    }
                    top_c--;
                }
                if(sta_c[top_c]=="(")
                {
                    top_c--;
                    if(sta_c[top_c]=="lg")
                    {
                        num[top_n]=log(num[top_n])/log(2);
                        top_c--;
                    }
                    else if(sta_c[top_c]=="sqrt")
                    {
                        num[top_n]=sqrt(num[top_n]);
                        top_c--;
                    }
                }
            }
        }
        while(top_n!=1)
        {
            num[top_n-1]=num[top_n-1]*num[top_n];
            top_n--;
        }
        if(num[1]>100000000)
            printf("TLE\n");
        else
        {
            printf("%.2lf\n",num[1]);
        }
    }
}

你可能感兴趣的:(表达式求值,ACM,题目)