时间复杂度

Problem G: 时间复杂度

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 6   Solved: 3

Description

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

1、 O(n) 

2、 O(lg(n))

3、 O(sqrt(n))

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

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

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

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

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

Input

第一行输入n (1n10000), m(1m100), 其中n为题目描述的数,m为算法复杂度的个数。

接下来m行,每行为一个串,每个串都包含O()任何括号里面的数据保证仅由n,lg(),sqrt(),*组成并且合法。如sample input所示。

Output

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

Sample Input

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)))

Sample Output

100000000.00
TLE
100.00
13.29
132877.12
170197.33

HINT


关于lg(n)C语言代码可以这样写


log(n) / log(2)


思路: 用一个数字栈num[]来保存数据,用一个符号栈stack[]来保存符号,符号只有几种,sqrt(用个s来表示,lg(用了l来表示,O(不用表示,直接跳过,*,n用本身表示,当扫到这些符号栈的时候,就可以将计算得出的数压入数据栈。当扫描到)时,就可以合并一个运算或两个数据。最后的数据栈num[]只有一个数,既答案num[1]
代码:
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
using namespace std;
char ss[110];
char stack[110];
double num[110];
int main(){
    int m,len,i,top,count;
    double n;
    scanf("%lf%d",&n,&m);
    while(m--){
        scanf("%s",&ss);
        len=strlen(ss);
        top=1;count=1;
        for(i=2;i<len;i++){
            if(ss[i]=='s'){
                stack[top++]='s';
                i+=4;
            }
            else if(ss[i]=='l'){
                stack[top++]='l';
                i+=2;
            }
            else if(ss[i]=='n')
                num[count++]=n;
            else if(ss[i]=='*')
                stack[top++]='*';
            else if(ss[i]==')'){
                while(stack[top-1]!='l'&&stack[top-1]!='s'&&top>0){//注意会有n*n*n这样的情况,所以需要用while
                    num[count-2]=num[count-1]*num[count-2];
                    count--;
                    top--;
                }
                if(stack[top-1]=='l'){
                    num[count-1]=log(num[count-1])/log(2);
                    top--;
                }
                else if(stack[top-1]=='s'){
                    num[count-1]=sqrt(num[count-1]);
                    top--;
                }
            }
        }
        if(num[1]>100000000)
            printf("TLE\n");
        else
            printf("%.2lf\n",num[1]);
    }
    return 0;
}

FROM:暑假训练第四场
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值