博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P3952 时间复杂度
阅读量:6565 次
发布时间:2019-06-24

本文共 2709 字,大约阅读时间需要 9 分钟。

毒瘤大模拟题!

看到这种又是字符串又是模拟的题目就很伤,很多的地方都考验细节。

看到这种处理循环的方式是后进先出,自然想到了用栈来模拟。

但是最主要的思路是怎么算复杂度?

其实说白了也简单:一个循环的复杂度 = 这个循环本身的复杂度 + 在里面嵌套的最大的复杂度

这里的每一个循环变量都是不重复的,如果重复直接判ERR。

那么我们就可以用一个循环变量来代表一个循环,利用他们记录一个循环本身的复杂度实际的复杂度

如何计算一个循环的本身时间复杂度?

  • 如果x不是\(n\),y是\(n\),这个循环是\(O(n)\)的。

  • 如果x和y都是\(n\),这个循环是\(O(1)\)的。

  • 如果x是\(n\)而y不是\(n\),那么这个循环不执行。

  • 如果x和y都是数字,比较他们的大小,当且仅当\(x \leq y\)时有\(O(1)\)的复杂度,否则不执行。

这里有一个很重要的思想:如果一个循环不执行,那么我就不去考虑这个循环内的任何时间复杂度!顶多看看会不会有语法错误就好了。

而有一个挺特殊的情况:如果任何循环都不执行的话是\(O(1)\)的。这个在样例已经跟你说了。

维护的时候直接用一个数字来维护,意义是\(n\)的几次方,所以\(O(1)\)用0来代替,不执行的情况我用-1来搞。

ERR总共有3种情况:

  1. F太多。这个在最后看看栈是不是空的就可以了。

  2. E太多。那么这个时候会发生栈下溢,特判解决。

  3. 变量重名。开一个used数组判一下就可以了。

总体来说不难,但是需要你有正确的思路!!!

这个故事告诉我们:写大模拟的时候一定要先想清楚所有的情况再写!

说人话就是:

\[\huge{Think \quad twice, code \quad once!}\]

代码:

#include
#include
#include
#include
#include
#include
using namespace std;string str[105];bool used[30];int source[30], comp[30];int id(char x){ return x - 'a' + 1;}int to_int(string x){ int len = x.length(), ans = 0; for(int i = 0; i < len; i++) ans = ans * 10 + x[i] - '0'; return ans;}int calc(string x, string y){ bool flag1 = (x[0] != 'n'), flag2 = (y[0] != 'n');// is a number if(flag1) { if(flag2) { int num1 = to_int(x), num_2 = to_int(y); if(num1 <= num_2) return 0; else return -1; } else return 1; } else { if(flag2) return -1; else return 0; }}int solve(int len, int expected){ memset(used, false, sizeof used); memset(source, 0, sizeof source); memset(comp, 0, sizeof comp); stack
sta; int ans = 0; for(int i = 1; i <= len; i++) { stringstream ss(str[i]); string opt, name, x, y; ss >> opt; if(opt[0] == 'F') { ss >> name >> x >> y; if(used[id(name[0])]) return 3;// ERR used[id(name[0])] = true; comp[id(name[0])] = source[id(name[0])] = calc(x, y); sta.push(name[0]); } else if(opt[0] == 'E') { if(sta.empty()) return 3;// ERR char name = sta.top(); sta.pop(); used[id(name)] = false; if(sta.empty()) { ans = std::max(ans, comp[id(name)]); } else { if(source[id(sta.top())] != -1) comp[id(sta.top())] = std::max(comp[id(sta.top())], source[id(sta.top())] + comp[id(name)]); } } } if(!sta.empty()) return 3;// ERR if(ans == expected) return 1; else return 2;}void print(int res){ if(res == 1) cout << "Yes\n"; else if(res == 2) cout << "No\n"; else if(res == 3) cout << "ERR\n"; else cout << "I AK NOIP!\n";}int main(){ int T; cin >> T; while(T--) { int len, expected; string temp; cin >> len >> temp; if(temp[2] == '1') expected = 0; else { stringstream ss(temp.substr(4)); ss >> expected; } for(int i = 0; i <= len; i++) getline(cin, str[i]); int res = solve(len, expected); print(res); } return 0;}

转载于:https://www.cnblogs.com/Garen-Wang/p/9934020.html

你可能感兴趣的文章
thinkphp学习笔记10—看不懂的路由规则
查看>>
Eclipse中SVN的安装步骤(两种)和使用方法[转载]
查看>>
JavaScript学习
查看>>
Codeforces Round #295 (Div. 2)B - Two Buttons BFS
查看>>
使用SQLServer 2008的CDC功能实现数据变更捕获
查看>>
iPad 3g版完美实现打电话功能(phoneitipad破解)
查看>>
VBoxGuestAdditions.iso下载地址
查看>>
EXPORT_SYMBOL的作用是什么
查看>>
BZOJ 1022 [SHOI2008]小约翰的游戏John AntiNim游戏
查看>>
PPTPD服务端搭建
查看>>
SyncTrayzor -- Windows tray utility / filesystem watcher / launcher for syncthing
查看>>
SANS top 20
查看>>
使用thumbnailator 时部分图片抛异常
查看>>
android-sdk-windows下载版
查看>>
phpc.sinaapp.com 加密的解密方法
查看>>
祝贺自己itpub和csdn双双荣获专家博客标题
查看>>
C/C++各种类型int、long、double、char表示范围(最大和最小)
查看>>
使用selector修改TextView中字体的颜色
查看>>
ngModel 值不更新/显示
查看>>
GitHub教程
查看>>