| #include<cstdio> |
| #include<iostream> |
| #include<stack> |
| #include<cmath> |
| |
| using namespace std; |
| |
| int T; |
| |
| bool isNumber(char x){ |
| if(x <= '9' && x >= '0') return true; |
| return false; |
| } |
| |
| string number(string ch){ |
| |
| string str = ""; |
| while(isNumber(ch[0])){ |
| |
| str.push_back(ch[0]); |
| ch.erase(0, 1); |
| } |
| return str; |
| } |
| |
| int prio(char x){ |
| if(x == '(' || x == ')') return 0; |
| if(x == '+' || x == '-') return 1; |
| if(x == '*' || x == '/') return 2; |
| if(x == '^') return 3; |
| return -1; |
| } |
| |
| int strToNumber(string ch){ |
| |
| int ans = 0, len = ch.length(); |
| for(int i = 0; i < len; ++i) |
| ans = ans*10 + ch[i] - '0'; |
| return ans; |
| } |
| |
| string suffix(string ch){ |
| |
| stack<char> sig; |
| string ans = ""; |
| while(ch != ""){ |
| |
| if(ch[0]==' '){ |
| ch.erase(0, 1); |
| } |
| else if(isNumber(ch[0])){ |
| string num = number(ch); |
| ans+=num+"."; |
| ch.erase(0, num.length()); |
| } |
| else if(ch[0]=='-' && isNumber(ch[1])){ |
| ch.erase(0, 1); |
| string num = number(ch); |
| ans+="-"+num+'.'; |
| ch.erase(0, num.length()); |
| } |
| else if(ch[0] == '('){ |
| sig.push('('); |
| ch.erase(0, 1); |
| } |
| else if(ch[0] == ')'){ |
| while(sig.top() != '('){ |
| ans.push_back(sig.top());ans.push_back('.'); |
| sig.pop(); |
| } |
| sig.pop(); |
| ch.erase(0, 1); |
| } |
| else{ |
| char now = ch[0]; |
| ch.erase(0, 1); |
| while(!sig.empty() && prio(sig.top()) >= prio(now)){ |
| ans.push_back(sig.top());ans.push_back('.'); |
| sig.pop(); |
| } |
| sig.push(now); |
| } |
| } |
| while(!sig.empty()){ |
| |
| ans.push_back(sig.top());ans.push_back('.'); |
| sig.pop(); |
| } |
| return ans; |
| } |
| |
| int solve(string ch){ |
| |
| stack<int> num; |
| while(ch != ""){ |
| |
| if(isNumber(ch[0])){ |
| string str = number(ch); |
| ch.erase(0, str.length()+1); |
| num.push(strToNumber(str)); |
| } |
| else if(ch[0] == '-' && isNumber(ch[1])){ |
| ch.erase(0, 1); |
| string str = number(ch); |
| ch.erase(0, str.length()+1); |
| num.push(0-strToNumber(str)); |
| } |
| else{ |
| char now = ch[0];ch.erase(0, 2); |
| int num1 = num.top();num.pop(); |
| int num2 = num.top();num.pop(); |
| if(now == '+') num.push(num2+num1); |
| if(now == '-') num.push(num2-num1); |
| if(now == '*') num.push(num2*num1); |
| if(now == '/') num.push(num2/num1); |
| if(now == '^') num.push(pow(num2, num1)); |
| } |
| } |
| return num.top(); |
| } |
| |
| int main() { |
| scanf("%d\n", &T);while(T--){ |
| string ch; |
| |
| getline(cin, ch); |
| |
| cout<<solve(suffix(ch))<<endl; |
| } |
| return 0; |
| } |
| #include<iostream> |
| #include<cstdio> |
| #include<cstring> |
| |
| using namespace std; |
| |
| char c[10000]; |
| int sgn=1, num1=0, num=0, tmp=0; |
| |
| int getWordEnd(int x){ |
| while(++x){ |
| if(c[x]==' '||c[x]=='\0') break; |
| } |
| return x; |
| } |
| |
| int same(char *x, char *y){ |
| int len = strlen(x), leny = strlen(y); |
| if(len!=leny) return 0; |
| for(int i = 0; i < len; ++i){ |
| if(x[i]!=y[i]) return 0; |
| } |
| return 1; |
| } |
| |
| void numOper(char* word){ |
| |
| |
| |
| if(same(word, "negative")) {sgn=-1;} |
| else if(same(word, "million")) {num1=(num+tmp)*1000000;num=0;tmp=0;} |
| else if(same(word, "thousand")) {num=(num+tmp)*1000;tmp=0;} |
| else if(same(word, "hundred")) {num+=tmp*100;tmp=0;} |
| |
| else if(same(word, "zero")) {tmp=0;} |
| else if(same(word, "one")) {tmp=1;} |
| else if(same(word, "two")) {tmp=2;} |
| else if(same(word, "three")) {tmp=3;} |
| else if(same(word, "four")) {tmp=4;} |
| else if(same(word, "five")) {tmp=5;} |
| else if(same(word, "six")) {tmp=6;} |
| else if(same(word, "seven")) {tmp=7;} |
| else if(same(word, "eight")) {tmp=8;} |
| else if(same(word, "nine")) {tmp=9;} |
| |
| else if(same(word, "ten")) {num+=10;} |
| else if(same(word, "eleven")) {num+=11;} |
| else if(same(word, "twelve")) {num+=12;} |
| else if(same(word, "thirteen")) {num+=13;} |
| else if(same(word, "fourteen")) {num+=14;} |
| else if(same(word, "fifteen")) {num+=15;} |
| else if(same(word, "sixteen")) {num+=16;} |
| else if(same(word, "seventeen")) {num+=17;} |
| else if(same(word, "eighteen")) {num+=18;} |
| else if(same(word, "nineteen")) {num+=19;} |
| else if(same(word, "twenty")) {num+=20;} |
| else if(same(word, "thirty")) {num+=30;} |
| else if(same(word, "forty")) {num+=40;} |
| else if(same(word, "fifty")) {num+=50;} |
| else if(same(word, "sixty")) {num+=60;} |
| else if(same(word, "seventy")) {num+=70;} |
| else if(same(word, "eighty")) {num+=80;} |
| else if(same(word, "ninety")) {num+=90;} |
| |
| |
| } |
| |
| void solve(){ |
| int len = strlen(c); |
| sgn=1, num1=0, num=0, tmp=0; |
| for(int i = 0; i < len;){ |
| int end = getWordEnd(i); |
| |
| char word[100]; |
| for(int j = i; j < end; ++j){ |
| word[j-i]=c[j]; |
| }word[end-i]='\0'; |
| |
| numOper(word); |
| i=end+1; |
| } |
| cout<<sgn*(num1+num+tmp)<<endl; |
| } |
| |
| int main(){ |
| while(1){ |
| cin.getline(c, 10000, '\n'); |
| if(c[0]=='\0') break; |
| solve(); |
| } |
| return 0; |
| } |
第一次使用指针构建数据结构,有一个非常大的bug就是priority_queue中的q.top()返回的是一个固定的地址的类,因此不能直接使用,应该new一个之后再使用。还有,尽量少的直接定义用node型变量而是用node* nd = new node来避免重复使用地址。
| #include <iostream> |
| #include <cstdio> |
| #include <algorithm> |
| #include <queue> |
| #include <cstring> |
| #include <typeinfo> |
| |
| using namespace std; |
| |
| struct node{ |
| int val = 0; |
| node *fa = nullptr; |
| node *son1 = nullptr; |
| node *son2 = nullptr; |
| bool operator < (const node& tmp) const{ |
| return val > tmp.val; |
| } |
| }; |
| priority_queue<node> q; |
| |
| int dfs(node* rt, int d){ |
| if(rt->son1 == nullptr && rt->son2 == nullptr){ |
| return (rt->val) * d; |
| } |
| return dfs(rt->son1, d+1) + |
| dfs(rt->son2, d+1); |
| } |
| |
| void test(){ |
| int* a, b; |
| cout<<typeid(a).name()<<' '<<typeid(b).name()<<endl; |
| } |
| |
| node* deepCopy(const node x){ |
| node* y; |
| y->val = x.val;y->son1 = x.son1;y->son2 = x.son2;y->fa = x.fa; |
| return y; |
| } |
| |
| int main(){ |
| |
| int T;cin>>T;while(T--){ |
| int n;cin>>n; |
| while(!q.empty()) q.pop(); |
| while(n--){ |
| int temp;cin>>temp; |
| node* tmp = new node;tmp->val = temp; |
| q.push(*tmp); |
| } |
| while(q.size() > 1){ |
| node* x1 = new node(q.top());q.pop(); |
| node* x2 = new node(q.top());q.pop(); |
| node* y = new node;y->val = x1->val + x2->val; |
| y->son1 = x1; y->son2 = x2; |
| x1->fa = x2->fa = y; |
| q.push(*y); |
| } |
| node* rt = new node(q.top());q.pop(); |
| |
| cout<<dfs(rt, 0)<<endl; |
| } |
| return 0; |
| } |
做法1:对森林中每棵并查集建立双向的enemy关系,每次合并相当于是合并最多4棵并查集(即a所在的、a敌对的、b所在的、b敌对的)。每个enemy只存在与树根中,其他节点中的enemy是无效量,从而保证唯一性。注意节点的enemy随时可能失去树根身份,所以使用时必须套上find(en[x])
。
| #include <iostream> |
| #include <cstdio> |
| #include <cstring> |
| |
| using namespace std; |
| |
| int fa[200000], en[200000]; |
| |
| int f(int x){ |
| if(x == fa[x]) return x; |
| return fa[x] = f(fa[x]); |
| } |
| |
| int main(){ |
| int T;cin>>T; |
| while(T--){ |
| int N, M; cin>>N>>M; |
| for(int i = 1; i <= N; ++i) {fa[i] = i;en[i] = 0;} |
| for(int i = 1; i <= M; ++i){ |
| char ch;int x, y;cin>>ch>>x>>y; |
| x = f(x); y = f(y); |
| if(ch == 'A'){ |
| if(x == y) cout<<"In the same gang."<<endl; |
| else if(f(en[x]) == y || f(en[y]) == x) cout<<"In different gangs."<<endl; |
| else cout<<"Not sure yet."<<endl; |
| } |
| else{ |
| if(f(en[x]) == y && f(en[y]) == x) continue; |
| if(f(en[x]) == 0 && f(en[y]) == 0) {en[x] = y; en[y] = x;continue;} |
| if(f(en[x])) fa[y] = f(en[x]); |
| if(f(en[y])) fa[x] = f(en[y]); |
| } |
| } |
| } |
| return 0; |
| } |
做法2:带权并查集,每次路径压缩时更新节点权值。注意路径压缩可以保证m次操作的最坏时间复杂度为,所以不需要担心额外进行操作会导致复杂度变高。
| #include <iostream> |
| #include <cstdio> |
| #include <cstring> |
| |
| using namespace std; |
| |
| int fa[200000], en[200000]; |
| |
| int f(int x){ |
| if(x == fa[x]) return x; |
| return fa[x] = f(fa[x]); |
| } |
| |
| int main(){ |
| int T;cin>>T; |
| while(T--){ |
| int N, M; cin>>N>>M; |
| for(int i = 1; i <= N; ++i) {fa[i] = i;en[i] = 0;} |
| for(int i = 1; i <= M; ++i){ |
| char ch;int x, y;cin>>ch>>x>>y; |
| x = f(x); y = f(y); |
| if(ch == 'A'){ |
| if(x == y) cout<<"In the same gang."<<endl; |
| else if(f(en[x]) == y || f(en[y]) == x) cout<<"In different gangs."<<endl; |
| else cout<<"Not sure yet."<<endl; |
| } |
| else{ |
| if(f(en[x]) == y && f(en[y]) == x) continue; |
| if(f(en[x]) == 0 && f(en[y]) == 0) {en[x] = y; en[y] = x;continue;} |
| if(f(en[x])) fa[y] = f(en[x]); |
| if(f(en[y])) fa[x] = f(en[y]); |
| } |
| } |
| } |
| return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效