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<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
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 <string.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <algorithm>
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; i<len-1; 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]);
}
}
}
相關推薦
373-時間複雜度(表示式求值)
在 ACM 裡面,計算複雜度是一項非常重要的事情,常見的複雜度格式有三種: O(n) O(lg(n)) O(sqrt(n)) 一個演算法往往有多種解法,每種解法的複雜度有上述常見的的複雜度組合成,例如排序的兩種演算法: 快速排序: 時間複雜度為
堆處理海量資料----求前k個最小的數--時間複雜度(n * log k)
通過閱讀July的書籍,發現裡面求前k個最小數有很多方法。但在面對處理海量資料處理的時候,不能 把全部資料都放在電腦記憶體中。這時用堆來處理,並把資料放在外存中,通過讀取檔案的方式來讀取。感覺該方法十分巧妙,時間複雜度(n*log k)。程式碼如下: #include&l
LeetCode 49. Group Anagrams 時間複雜度(O(k*n))
時間複雜度(O( k*n)) class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { un
Boolean Expressions(表示式求值)
描述The objective of the program you are going to produce is to evaluate boolean expressions as the one shown next:Expression: ( V | V ) & F & ( F |
資料結構——棧的應用(表示式求值)(C語言)
char Precede(char t1, char t2)函式用於輸出t1,t2兩個運算子的優先順序(t1為先出現的運算子(已經壓入棧OPTR中),t2為後出現的運算子) char Precede(char t1, char t2){ int
LeetCode 39. Combination Sum 時間複雜度(O( n^k))
時間複雜度(O( n^k)),思想,DFS 深度遍歷 class Solution { public: vector<vector<int>> combinationSum(vector<int>& candidates,
華為機試:四則運算(表示式求值)
題目描述請實現如下介面/* 功能:四則運算 * 輸入:strExpression:字串格式的算術表示式,如: "3+2*{1+2*[-4/(8-6)+7]}" * 返回:算術表示式的計算結果 */publicstaticint calculate(St
鏈棧(表示式求值)
#include<cstdio> #include<cstdlib> #include<cstring> typedef struct Snode { char data; struct Snode *next; }Snode, *Li
BFPRT演算法:時間複雜度O(n)求第k小的數字(分治演算法+快排)
去年寫了一篇《分治演算法 求第 k k k小元素
看動畫輕鬆理解時間複雜度(一)
原文連結:看動畫輕鬆理解時間複雜度(一) 演算法(Algorithm)是指用來操作資料、解決程式問題的一組方法。對於同一個問題,使用不同的演算法,也許最終得到的結果是一樣的,比如排序就有前面的十大經典排序和幾種奇葩排序,雖然結果相同,但在過程中消耗的資源和時間卻會有很大的區別,比如快速排序與猴子排
看動畫輕鬆理解時間複雜度(二)
上篇文章講述了與複雜度有關的大 O 表示法和常見的時間複雜度量級,這篇文章來講講另外幾種複雜度: 遞迴演算法的時間複雜度(recursive algorithm time complexity),最好情況時間複雜度(best case time complexity)、最壞情況
資料結構第二次作業(表示式求值【棧模擬】)
實驗題目:棧的應用-算術表示式求值 實驗目的 : 1.掌握棧的定義及實現; 2.掌握利用棧求解算術表示式的方法。 實驗內容: 通過修改完善教材中的演算法3.4,利用棧來實現算術表示式求值的演算法。對演算法3.4中呼叫的幾個函式要
最長遞增子序列,時間複雜度(O(nlogn))
package com.kailong.datastures; import java.util.Arrays; /** * Created by Administrator on 2017/4/17. * 最長遞增子序列 */ public class Find
表示式求值(中綴轉字尾及字尾表示式求值)
。中綴表示式轉字尾表示式: 中綴表示式轉字尾表示式遵循以下原則: 1.遇到運算元,直接輸出; 2.棧為空時,遇到運算子,入棧; 3.遇到左括號,將其入棧; 4.遇到右括號,執行出棧操作,
棧及其應用(表示式求值、括號匹配)
一、棧(stack) 1、棧的特點 棧(Stack)是一種線性儲存結構,它具有如下特點: 【Note】: (1)棧中的資料元素遵守”先進後出”(First In Last Out)的原則,簡
棧---定義、應用(遞迴、字尾表示式實現數學表示式求值)
一、定義 棧是限定僅在表尾進行插入和刪除操作的線性表。因此,棧的表尾端稱為棧頂;表頭端稱為棧底。不含任何資料元素的棧稱為空棧。棧又稱為後進先出(Last In First Out)的線性表,簡稱LIF0結構。 理解棧的定義需要注意:首先它是一個線性表,也即棧
排序演算法--時間複雜度(平均時間,最壞情況)、空間複雜度
1、時間複雜度:一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式f(n),演算法的時間量度記作:
八大排序演算法JAVA實現(時間複雜度O(n-logn)篇)
本文講述時間複雜度為n*logn的排序演算法:歸併排序、快速排序、堆排序以及希爾排序的原理、Java實現以及變形應用。 一、歸併排序 原理:把兩個有序數列合併為一個有序數列。需遞迴實現。 Java實現: 1 public int[] mergeSort(in
八大排序演算法JAVA實現(時間複雜度O(n-n)篇)
本文主要描述3個時間複雜度為n2的排序演算法:氣泡排序、選擇排序、插入排序。 1.氣泡排序:由陣列頭部開始,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。每次交換完成後,當前陣列最大值就會被放在最後。 1 public int[] bubbleSort
時間複雜度(演算法分析)
演算法分析 在現在這個資訊爆炸的時代,處理資料的量也越來越大。所以人們在用計算機來解決日常生活生產的問題的時候難免會有這樣的疑問。 我的程式會執行多長時間? 我的程式會耗多少的記憶體? 這次我們就來簡單討論一下第一個“我的程式會執行多長時間?”。