pts: ?
T1: 100
T2: 0/40/50
T3: 30
数论,不定方程,同余,中国剩余定理,构造,找规律
solution:
大表找规律: a * b - a - b
还有个 long long
模拟,字符串,栈
solution
多组数据跑完一组直接 return 0 了 /jk (我是benb)
不会写模拟qwq
/* work by:Ariel_ O(1) = 0; O(n ^ 1) = 1; O(n ^ 2) = 2;…… */ #include <iostream> #include <cstring> #include <cstdio> #include <stack> #include <string> using namespace std; int read(){ int x = 0,f = 1; char c = getchar(); while(c < '0'||c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') {x = x*10 + c - '0'; c = getchar();} return x*f; } int m, L, T;//T为它给的时间复杂度 string tim, code[110]; int calc(int &p, string s){//计算一个代码中变量的两个边界 int ans = 0, len = s.size(); while(s[p] < '0'|| s[p] > '9' && p <= len){ if(s[p] == 'n'){p++; return 1234567;} p++; } while(s[p] >= '0' && s[p] <= '9'){ ans *= 10, ans += s[p] - '0', p++; } return ans; } stack<int> s, S; stack <char> c; stack <int> id; void subtask(){ int T = 0, cnt = 0, flag = 1, opt = 1, vis[27], o = 0, fag[110], jl[110]; memset(jl, 0, sizeof jl); memset(fag, 0, sizeof fag);//记录这行程序能不能进去 memset(vis, 0, sizeof vis); int len = tim.size(), p = 3; if(tim[2] == 'n'){//计算出他给出的时间复杂度 while(tim[p] < '0'|| tim[p] > '9') p++; while(tim[p] >= '0' && tim[p] <= '9') T *= 10, T += tim[p] - '0', p++; } int maxx = -0x3f3f3f3f; for(int i = 1; i <= L; i++) { p = 4; if(code[i][0] == 'F'){ S.push(i); id.push(i); if(vis[code[i][2] - 'a' + 1]){opt = 0;break;} c.push(code[i][2]);//证明这个变量已经用过了 vis[code[i][2] - 'a' + 1] = 1; int x = calc(p, code[i]), y = calc(p, code[i]); if(y - x > 100 && o == 0){cnt++; jl[i] = 1;maxx = max(cnt, maxx);} else if(x > y) fag[i] = 1, o++;//该行程序不能进去 s.push(i); } else if(code[i][0] == 'E'){ vis[c.top() - 'a' + 1] = 0;//结束了之后变量就可以用了 if(fag[id.top()]){o--, id.pop();} else id.pop(); c.pop(); if(S.empty()){flag = 0; break;} else S.pop(); maxx = max(cnt, maxx); int tp = s.top(); s.pop(); if(jl[tp]) cnt--; } } if(!opt) printf("ERR\n"); else if(!flag)printf("ERR\n"); else if(maxx == T) printf("Yes\n"); else printf("No\n"); } int main(){ m = read(); while(m--) { L = read(); getline(cin, tim); for (int i = 1; i <= L; i++) getline(cin, code[i]); int cnt_F = 0, cnt_E = 0; for (int i = 1; i <= L; i++) { if(code[i][0] == 'F') cnt_F++; else if(code[i][0] == 'E') cnt_E++; } if (cnt_E != cnt_F) {printf("ERR\n");} else subtask(); } puts(""); return 0; }
记忆化搜索,搜索,最短路
solution
30 pts
\(K = 0\) 最短路计数
100 pts
先建反图,然后跑一遍 \(spfa\) ,每个点到终点的最短路就求出来了
统计答案 ?正着跑一遍
\(f_{u,x}\) 表示到达 \(u\) 点还剩 \(x\) 步可以绕的方案数
\(f[u][x] = \sum_{v}f[v][x - (dis[u] + e[i].w - dis[v])]\)
到达 \(n\) 就是 1
有环答案就为 -1