Problem G: 时间复杂度
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 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)
现在给定你一个n,m个算法复杂度,请确定这些复杂度是否会超时。若复杂度计算结果大于100000000,则为超时(TLE),否则输出计算的复杂度,输出的结果保留两位小数。
( lg(n)表示以2为底数,n为真数的值 )
Input
第一行输入n (1≤n≤10000), m(1≤m≤100), 其中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:暑假训练第四场