计蒜客 时间复杂度 (模拟) 洛谷 P3952 时间复杂度
生活随笔
收集整理的這篇文章主要介紹了
计蒜客 时间复杂度 (模拟) 洛谷 P3952 时间复杂度
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
鏈接 : Here!
思路 :
這是一道大模擬, 區(qū)分好情況就沒(méi)問(wèn)題了
循環(huán)構(gòu)成部分 : $F , x , i , j$ 和 $E$ , 需要注意的是 $i , j$,
- 分析 $i, j$ 的情況 : - 當(dāng) $i, j$ 全為 $n$ 的時(shí)候, 復(fù)雜度為 $O(1)$- 當(dāng) $i, j$ 為 $number$ 和 $n$ 的時(shí)候復(fù)雜度為 $O(n)$- 當(dāng) $i, j$ 為 $n$ 和 $number$ 的時(shí)候復(fù)雜度為 $O(0)$- 當(dāng) $i, j$ 全為 $number$ 時(shí), 需要考慮- 如果 $i > j$ 復(fù)雜度為 $O(0)$- 否則復(fù)雜度為 $O(1)$分析多個(gè)循環(huán)的復(fù)雜度情況 :
- | 外層復(fù)雜度 \\ 內(nèi)層復(fù)雜度 | O(0) | O(1) | O($n^{w_2}$) | | -------------- | ------------ | ------------ | ------------------------------------ | | O(0) | O(0) | O(0) | O(0) | | O(1) | O(1) | O(1) | O(n) | | O($n^{w_1}$) | O($n^{w_1}$) | O($n^{w_1}$) | multiply(O($n^{w_1}$), O($n^{w_2}$)) |- 然后**分析循環(huán)并列**的復(fù)雜度情況 : **選取并列復(fù)雜度較大的那個(gè)**
- 首先分析循環(huán)內(nèi)外層嵌套的復(fù)雜度情況 :錯(cuò)誤情況 :
- $F$ 和 $E$ 不匹配
- 預(yù)期復(fù)雜度與實(shí)際復(fù)雜度不匹配分析完成之后直接敲代碼就$ok$了, 如果我們將整個(gè)大的循環(huán)嵌套并列的結(jié)構(gòu)抽象成一棵樹(shù)的話, 那就會(huì)發(fā)現(xiàn), 必須存一下當(dāng)前層的最大復(fù)雜度
?
代碼 :
/*************************************************************************> File Name: 時(shí)間復(fù)雜度.cpp> Author: > Mail: > Created Time: 2017年11月22日 星期三 18時(shí)26分04秒************************************************************************/#include <cstdio> #include <iostream> #include <string> #include <stack> using namespace std;struct expr {char var; // 記錄變量名 string st, ed; // 記錄循環(huán)的開(kāi)始終止位置string tempO; // 記錄復(fù)雜度string nowLayerO; // 記錄當(dāng)前層的最大復(fù)雜度 }; int T, n; string des; // 記錄預(yù)測(cè)復(fù)雜度int calNumber(const string &str) {int temp = 0;for (int i = 0 ; i < str.length() ; ++i) {temp = temp * 10 + str[i] - '0';}return temp; }// 計(jì)算復(fù)雜度 void calComplexity(expr &exp) {// case 1 : 如果st,ed全為n的話if (exp.st == "n" && exp.ed == "n") {exp.tempO = "1";return;}// case 2 : 如果st為數(shù)字,ed為n if (exp.st != "n" && exp.ed == "n") {exp.tempO = "n";return;}// case 3 : 如果st為n,ed為數(shù)字if (exp.st == "n" && exp.ed != "n") {exp.tempO = "0";return;}// case 4 : 如果st,ed全為數(shù)字且st <= ed// case 5 : 如果st,ed全為數(shù)字且st > edint st_num = calNumber(exp.st); int ed_num = calNumber(exp.ed);if (st_num <= ed_num) {exp.tempO = "1";} else {exp.tempO = "0";}return; }// 計(jì)算str中的冪指數(shù), str為n^w(w >= 1),當(dāng)w為1的時(shí)候是可以省略的 int calExponent(const string &str) {// 特殊情況if (str == "n") {return 1;}int ret = 0;for (int i = 2 ; i < str.length() ; ++i) {ret = ret * 10 + str[i] - '0';}return ret; }// 復(fù)雜度相乘 // 如果外層循環(huán)是O(0)那么a * b -> O(0) // 如果內(nèi)層循環(huán)是O(0)那么a * b -> a的復(fù)雜度 // a代表外層復(fù)雜度, b代表內(nèi)層復(fù)雜度 string multiComplexity(const string &a, const string &b) {string ret = "";if (a == "0") {ret = "0";} else if (a == "1") {if (b == "0") {ret = "1";} else {ret = b;}} else {if (b == "0") {ret = a;} else if (b == "1") {ret = a;} else {// 如果能進(jìn)入這里首先可以確定a,b為n^w// 且a,b的w >= 1因此tstr直接寫個(gè)前綴n^是完全沒(méi)問(wèn)題的int expon1 = calExponent(a);int expon2 = calExponent(b);string tstr1 = "n^";string tstr2 = "";expon1 += expon2;while (expon1) {tstr2 += (char)((expon1 % 10) + '0');expon1 /= 10;}for (int i = tstr2.length() - 1 ; i >= 0 ; --i) {tstr1 += tstr2[i];}ret = tstr1;}}return ret; }// 復(fù)雜度相加,選出復(fù)雜度較大的那個(gè) string addComplexity(const string &a, const string &b) {string ret = "";if (a == "0") {ret = b;} else if (a == "1") {ret = (b == "0" ? a : b);} else {if (b == "0" || b == "1") {ret = a;} else {int expon1 = calExponent(a);int expon2 = calExponent(b);ret = (expon1 > expon2 ? a : b);}}return ret; }void read() {scanf("%d", &T);while (T--) {int vis[30] = {0}, flag = 0; // 標(biāo)記是否出現(xiàn)變量名沖突cin >> n >> des;expr exp[n];stack<expr> myStack;string sum = "0";string maxO = "0";for (int i = 0 ; i < n ; ++i) {char firstCh;cin >> firstCh;if (firstCh != 'E') {cin >> exp[i].var >> exp[i].st >> exp[i].ed;if (vis[exp[i].var - 'a']) {flag = 1;}vis[exp[i].var - 'a'] = 1;calComplexity(exp[i]);// cout << "exp.tempO : " << exp[i].tempO << endl;exp[i].nowLayerO = exp[i].tempO;myStack.push(exp[i]);} else {// 如果遇到E則該彈棧計(jì)算了 // 并且更新新棧頂當(dāng)前層數(shù)最大復(fù)雜度// 如果空棧還彈,那說(shuō)明ERRif (myStack.empty()) {flag = 1;continue;}expr topExp = myStack.top(); myStack.pop();vis[topExp.var - 'a'] = 0;// 先獲取當(dāng)彈出的當(dāng)前層最大復(fù)雜度string temp1 = topExp.nowLayerO;// 暫存一下當(dāng)前最大復(fù)雜度maxO = topExp.nowLayerO;// 如果能向上更新這個(gè)最大復(fù)雜度if (!myStack.empty()) {topExp = myStack.top();myStack.pop();topExp.nowLayerO = addComplexity(topExp.nowLayerO, multiComplexity(topExp.tempO, temp1));myStack.push(topExp);}// cout << " maxO : " << maxO << endl;}// 如果棧為空,那么說(shuō)一個(gè)loop已經(jīng)結(jié)束了if (myStack.empty()) {sum = addComplexity(sum, maxO);maxO = "0";}}if (flag || !myStack.empty() || (n & 1)) {printf("ERR\n");} else {// cout << "ans : " << sum << endl;if (sum == "n") sum = "n^1";if (sum == "0") sum = "1";sum = "O(" + sum + ")";if (sum == des) {printf("Yes\n");} else {printf("No\n");}}} } int main() {read();return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/WArobot/p/7884386.html
總結(jié)
以上是生活随笔為你收集整理的计蒜客 时间复杂度 (模拟) 洛谷 P3952 时间复杂度的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 多线程ping
- 下一篇: 一招教你掌握肌肉发力的感觉