**链接 : ** Here!

**思路 : **

  • 这是一道大模拟, 区分好情况就没问题了

  • 循环构成部分 : $F , x , i , j$ 和 $E$ , 需要注意的是 $i , j$,

    - 分析 $i, j$ 的情况 :
    - 当 $i, j$ 全为 $n$ 的时候, 复杂度为 $O(1)$
    - 当 $i, j$ 为 $number$ 和 $n$ 的时候复杂度为 $O(n)$
    - 当 $i, j$ 为 $n$ 和 $number$ 的时候复杂度为 $O(0)$
    - 当 $i, j$ 全为 $number$ 时, 需要考虑
    - 如果 $i > j$ 复杂度为 $O(0)$
    - 否则复杂度为 $O(1)$
  • 分析多个循环的复杂度情况 :

    - 首先分析循环内外层嵌套的复杂度情况 :

       - | 外层复杂度 \\ 内层复杂度 | 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}$)) | - 然后**分析循环并列**的复杂度情况 : **选取并列复杂度较大的那个**
  • 错误情况 :

    - $F$ 和 $E$ 不匹配

    - 预期复杂度与实际复杂度不匹配

  • 分析完成之后直接敲代码就$ok$了, 如果我们将整个大的循环嵌套并列的结构抽象成一棵树的话, 那就会发现, 必须存一下当前层的最大复杂度

代码 :

/*************************************************************************
> File Name: 时间复杂度.cpp
> Author:
> Mail:
> Created Time: 2017年11月22日 星期三 18时26分04秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <string>
#include <stack>
using namespace std; struct expr {
char var; // 记录变量名
string st, ed; // 记录循环的开始终止位置
string tempO; // 记录复杂度
string nowLayerO; // 记录当前层的最大复杂度
};
int T, n;
string des; // 记录预测复杂度 int calNumber(const string &str) {
int temp = 0;
for (int i = 0 ; i < str.length() ; ++i) {
temp = temp * 10 + str[i] - '0';
}
return temp;
} // 计算复杂度
void calComplexity(expr &exp) {
// case 1 : 如果st,ed全为n的话
if (exp.st == "n" && exp.ed == "n") {
exp.tempO = "1";
return;
}
// case 2 : 如果st为数字,ed为n
if (exp.st != "n" && exp.ed == "n") {
exp.tempO = "n";
return;
}
// case 3 : 如果st为n,ed为数字
if (exp.st == "n" && exp.ed != "n") {
exp.tempO = "0";
return;
}
// case 4 : 如果st,ed全为数字且st <= ed
// case 5 : 如果st,ed全为数字且st > ed
int st_num = calNumber(exp.st);
int ed_num = calNumber(exp.ed);
if (st_num <= ed_num) {
exp.tempO = "1";
} else {
exp.tempO = "0";
}
return;
} // 计算str中的幂指数, str为n^w(w >= 1),当w为1的时候是可以省略的
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;
} // 复杂度相乘
// 如果外层循环是O(0)那么a * b -> O(0)
// 如果内层循环是O(0)那么a * b -> a的复杂度
// a代表外层复杂度, b代表内层复杂度
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 {
// 如果能进入这里首先可以确定a,b为n^w
// 且a,b的w >= 1因此tstr直接写个前缀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;
} // 复杂度相加,选出复杂度较大的那个
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; // 标记是否出现变量名冲突
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则该弹栈计算了
// 并且更新新栈顶当前层数最大复杂度
// 如果空栈还弹,那说明ERR
if (myStack.empty()) {
flag = 1;
continue;
}
expr topExp = myStack.top();
myStack.pop();
vis[topExp.var - 'a'] = 0;
// 先获取当弹出的当前层最大复杂度
string temp1 = topExp.nowLayerO;
// 暂存一下当前最大复杂度
maxO = topExp.nowLayerO; // 如果能向上更新这个最大复杂度
if (!myStack.empty()) {
topExp = myStack.top();
myStack.pop(); topExp.nowLayerO = addComplexity(topExp.nowLayerO, multiComplexity(topExp.tempO, temp1)); myStack.push(topExp);
}
// cout << " maxO : " << maxO << endl;
}
// 如果栈为空,那么说一个loop已经结束了
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;
}

计蒜客 时间复杂度 (模拟) & 洛谷 P3952 时间复杂度的更多相关文章

  1. 洛谷 P3952 时间复杂度 解题报告

    P3952 时间复杂度 题目描述 小明正在学习一种新的编程语言A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会 ...

  2. 洛谷 - P3952 - 时间复杂度 - 模拟

    https://www.luogu.org/problemnew/show/P3952 这个模拟,注意每次进入循环的时候把新状态全部入栈,退出循环的时候就退栈. 第一次就错在发现ERR退出太及时,把剩 ...

  3. 洛谷P3952 时间复杂度【字符串】【模拟】

    题目描述 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序 ...

  4. 2018.11.02 洛谷P3952 时间复杂度(模拟)

    传送门 惊叹考场dubuffdubuffdubuff. 这题还没有梭哈难啊233. 直接按照题意模拟就行了. 代码: #include<bits/stdc++.h> using names ...

  5. 洛谷P3952 时间复杂度(模拟)

    题意 题目链接 Sol 咕了一年的题解..就是个模拟吧 考场上写的递归也是醉了... 感觉一年自己进步了不少啊..面向数据编程的能力提高了不少 #include<bits/stdc++.h> ...

  6. 洛谷 P3952 时间复杂度【模拟】

    把No写成NO,WA了一发-- 现在看这题也不难-- 用一个栈,记一下前面F的字母,是否合法,合法的有多长,每次入栈弹栈即可 #include<iostream> #include< ...

  7. 洛谷P3952 时间复杂度

    大毒瘤...... 时隔快半年我终于花了两个小时堪堪A掉这一题...果然我还没有准备好. 想法:用DFS模拟递归. 时间复杂度的处理:每层循环取max,然后相加. 最大难点:各种繁杂而令人发指的特判. ...

  8. 洛谷 P3952时间复杂度 (本地AC测评RE的伪题解)

    [题目描述] 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写 ...

  9. 计蒜客NOIP模拟赛6 D1T1Diamond-square

    Diamond-square 算法是一种能够用于生成噪声的算法,现在我们考虑这个算法的一个变种. 你有一个 2^n\times 2^n2​n​​×2​n​​ 的网格,一共有 (2^n+1)^2(2​n ...

随机推荐

  1. 利用 Gearman 实现系统错误报警功能

    Gearman 是什么? Gearman是一个用来把工作委派给其他机器.分布式的调用更适合做某项工作的机器.并发的做某项工作在多个调用间做负载均衡.或用来在调用其它语言的函数的系统. Gearman ...

  2. 初探boost之noncopyable学习笔记

    noncopyable 功能 同意程序轻松实现一个不可复制的类. 需包括头文件 #include<boost/noncopyable.hpp>     或 #include<boos ...

  3. POJ3255 Roadblocks 严格次短路

    题目大意:求图的严格次短路. 方法1: SPFA,同时求单源最短路径和单源次短路径.站在节点u上放松与其向量的v的次短路径时时,先尝试由u的最短路径放松,再尝试由u的次短路径放松(该两步并非非此即彼) ...

  4. 【转】iOS程序自动检测更新的实现 -- 思路不错

    原文网址:http://blog.csdn.net/davidsph/article/details/8931718 之前项目需要用到app自动更新的功能,现将实现方案分享出来.iOS程序自动提示更新 ...

  5. java javax.annotation.Resource注解的详解

    转自:https://www.jb51.net/article/95456.htm java 注解:java javax.annotation.Resource  当我们在xml里面为类配置注入对象时 ...

  6. [TB-Technology] 淘宝在数据处理领域的项目及开源产品介绍

    淘宝在数据存储和处理领域在国内互联网公司中一直保持比较靠前的位置,而且由于电子商务领域独特的应用场景,淘宝在数据实时性和大规模计算及挖掘方面一直在国内保持着领先,因此积累了很多的实践的经验和产品. T ...

  7. AUTOCAD2013 以上利用ACCORECONSOLE+ SCR后台批量清理图纸

    无意中浏览到南胜大神的博客,https://www.cnblogs.com/NanShengBlogs/p/10957489.html 受此启发,特意改装此方法用于批量清理图纸,效果极佳. 详细介绍详 ...

  8. OpenCASCADE 包说明

    转载地址:http://www.cppblog.com/eryar/archive/2012/06/30/180916.html 一.简介 Introduction to Package gp gp是 ...

  9. 全面改造升级内部OA系统

    项目功能集团的OA办公系统,分别是销售管理系统.财务付款系统.原料采购系统.成品采购系统.担保系统和库房管理系统业务现状成品采购系统.库房管理系统.销售管理系统是Access开发的C/S系统,采用本地 ...

  10. React+webpack

    webPack + React 步骤: 1. 创建文件夹 src 源代码目录 main.js 打包的入口文件 App.js 项目的根组件 import React,{Component} from ' ...