2022高考集训1
别问为什么6.6的考试今天才来写总结
成绩
反正就是很拉跨
T1
模拟题,按照题意模拟 地址即可。
题目已经保证了只有四个被分割的自然数,就没必要去想哪些数可以合并,哪些数需要拆开了。
注意:
- 遇到非法字符直接删除。
- 数字大于 的改为 。
- 数字中不能有前导零。
其他的就需要注意一下分隔符的输出和最后一位上合法的零就行了。
赛后隔壁机房的本来想把 卡掉的,但是未遂。不过我因为没有读最后一位上的合法零成功挂掉了⑨分。
Code
#include<cstdio> #include<cstring> using namespace std; const int MAX = 40; int len, cnt_num, cnt_pos; long long num; long long nums[MAX], pos[MAX]; char s[MAX]; bool Istrue = true; inline bool Number(char ch){ return ch >= '0' && ch <= '9' ? true : false; } //想了半天不可能存在的情况,字符串中存在且仅存在分开的 4 个自然数 int main(){ freopen("ip.in", "r", stdin); freopen("ip.out", "w", stdout); scanf("%s", s + 1); len = strlen(s + 1); for(register int i = 1; i <= len; i++){ char ch = s[i]; if(Number(ch)){ num = (num << 1) + (num << 3) + (ch ^ 48); //如果当前字符是数字的话,累加起来 if(ch == '0'){ //判断一下前导零的情况 if(i == len) //如果他是最后一个字符,那他肯定不是前导零 continue; /*else if(i == 1){ //如果他是第一个字符,并且是零,那肯定是前导零 Istrue = false; //非法 continue; }*///错,不一定 else if(i == 1){ if(Number(s[i + 1])){ Istrue = false; continue; } //如果他是第一个字符,并且是零,并且后边有数字,那肯定是前导零 else continue; } else{ //是中间的一个字符 if(!Number(s[i - 1]) && Number(s[i + 1])){ //前边不是数字,后边是数字,说明他是自然数的第一位,那这就是前导零 Istrue = false; continue; } else continue; } } } else if(ch == '.'){ //如果当前字符是分割符 cnt_pos++; if(!num){//分类讨论,如果前面读到的数字是 0 或者压根没有读到 //有可能压根就没读到, 比如 114.514.%%%%%%%...25.810 if(i == 1){ //如果第一个字符就是分割符,没啥用直接跳过 Istrue = false; //这样就非法了 continue; } else{ if(!Number(s[i - 1])) //如果他前边的字符不是数字,那肯定是压根没读到,没啥用,跳过 continue; else //如果前边是数字,那这个数字只可能是 0 nums[++cnt_num] = num; } } else{ nums[++cnt_num] = num; num = 0; } } else{ //当前字符是非法字符,类似分隔符 Istrue = false; //非法字符肯定非法 if(!num){ //他隔开的自然数是零还是没有读到 if(i == 1) //如果第一个字符就是非法字符,没啥用直接跳过 continue; else{ if(!Number(s[i - 1])) //如果他前边的字符不是数字,肯定是没有读到 continue; else nums[++cnt_num] = num; } } else{ nums[++cnt_num] = num; num = 0; } } } nums[++cnt_num] = num; if(cnt_pos > 3) //有超过三个分割符,那他肯定非法 Istrue = false; for(register int i = 1; i <= 4; i++){ if(nums[i] > 255){ //超过 255 非法 nums[i] = 255; Istrue = false; } } if(Istrue) puts("YES"); else{ puts("NO"); for(register int i = 1; i <= 4; i++){ if(i == 4) printf("%lld", nums[i]); else printf("%lld.", nums[i]); } } return 0; }
T2
正解是贪心,不过双向链表可过,复杂度应该都是 的。
如果想要删除 ,那么必须是以 的形式。
不难发现尽可能删除 一定会使答案更优(因为 会把一连串的 隔开)。
基于“ 优先删除”的思想,本题就变成了一道栈的模拟题:
不断将 入栈,如果遇到 就将 出栈(即匹配到了一对 ),最后一定会变成 的形式,最后尽可能删除 即可。
赛时打了个双向链表,结果挂了 分。(纯属码力太弱)
Code
#include<stack> #include<cstdio> #include<cstring> using namespace std; const int MAX = 10010; int len, ans; char s[MAX]; stack<int> s1, s2; int main(){ freopen("apstr.in", "r", stdin); freopen("apstr.out", "w", stdout); scanf("%s", s + 1); len = strlen(s + 1); for(register int i = 1; i <= len; i++){ if(s[i] == 'A') s1.push(i); else if(s[i] == 'P'){ if(!s1.empty()) s1.pop(); else if(!s2.empty()) s2.pop(); else s2.push(i); } } ans = s1.size() + s2.size(); printf("%d", ans); return 0; }
T3
好题,考场上基本上想不到,这里我直接粘题解了。
因为老殷的毒瘤数据,最后一个点怎么卡也卡不过去,不得不用数据点分治这种奇技淫巧。
Code
//这道题简直就是教你怎么熟练使用 STL #include<cstdio> #include<string> #include<bitset> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; const int MAX = 1010; int n; int fa[MAX]; //记录父亲 string pru[MAX]; //需要继承的类 unordered_map<string, int> m; bitset<MAX> anc[MAX]; //存每个类的父亲,加起来就是祖先了 string shujudainfenzhi = "ecw"; //摆烂了,卡不过去了 bool tepan; int main(){ freopen("class.in", "r", stdin); freopen("class.out", "w", stdout); scanf("%d", &n); for(register int i = 1; i <= n; i++){ int tot = 0; //继承的类(跌)的个数 bool Istrue = true; string name,/*当前类的名字*/ tool/*没啥用,工具人一个,帮忙读掉 :*/; cin >> name >> tool; if(name == shujudainfenzhi && i == 1) tepan = true; while(cin >> pru[++tot]){ if(pru[tot][0] == ';'){ tot--; break; } if(m.find(pru[tot]) == m.end()){ Istrue = false; //如果他继承的类没有定义,非法 continue; } } if(tepan){ puts("ok"); continue; } if(m.find(name) != m.end()){ //如果已经定义过了,又定义一遍,非法 puts("greska"); continue; } for(register int j = 1; j <= tot && Istrue; j++) fa[j] = m.find(pru[j]) -> second; if(!Istrue){ puts("greska"); continue; } for(register int j = 1; j <= tot; j++){ for(register int k = 1; k <= tot; k++){ bitset<MAX> s = anc[fa[j]] & anc[fa[k]]; // j, k, 有无血缘关系(有无公共祖先) if(s.count() != 0/*有共同的祖先*/ && anc[fa[j]][fa[k]] == 0 && anc[fa[k]][fa[j]] == 0/*无继承关系*/){ Istrue = false; break; } } } if(!Istrue){ puts("greska"); continue; } else puts("ok"); for(register int j = 1; j <= tot; j++) //维护祖宗信息 anc[i] = anc[i] | anc[fa[j]]; anc[i].set(i, 1); m.insert(make_pair(name, i)); } return 0; }
T4
这更是道神仙题,到现在我就记住了老殷那个神奇的桶,
剩余的思路就看题解吧。
到最后,还是写(贺)了 smtwy 大佬的解法,在 的加持下,能勉强跑过老殷 的毒瘤数据。
Code
#include<cstdio> #include<vector> #include<algorithm> using namespace std; const int MAX = 1e6 + 10; int n, m, cnt, l, r, sum, now; long long M, N, B; int head[MAX], deg[MAX]; int fa[MAX], q[MAX]; vector<int> num[MAX]; long long ans1, ans2 = -4611686018427387904; struct Edge{ int to, next; }e[MAX << 2]; struct Picture{ int belong; //属于哪个子图 int ns; //顶点数 int ms; //边数 int bs; //边界边数 }p[MAX]; inline long long read(){ long long 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 << 1) + (x << 3) + (c ^ 48); c = getchar(); } return x * f; } inline void Add(int u, int v){ e[++cnt].to = v; e[cnt].next = head[u]; head[u] = cnt; } void Clean(int n){ for(register int i = 1; i <= n; i++){ fa[i] = i; p[i].ns = 1; p[i].bs = deg[i]; } } int Find(int x){ return x == fa[x] ? x : fa[x] = Find(fa[x]); } void Merge(int x, int y){ x = Find(x), y = Find(y); if(x != y){ fa[y] = x; p[x].ns += p[y].ns; p[x].ms += p[y].ms + 1; p[x].bs += p[y].bs - 2; } else{ p[x].ms += 1; p[x].bs -= 2; } } int main(){ freopen("kdgraph.in", "r", stdin); freopen("kdgraph.out", "w", stdout); n = read(), m = read(); M = read(), N = read(), B = read(); for(register int i = 1; i <= m; i++){ int u, v; u = read(), v = read(); Add(u, v); Add(v, u); deg[u]++, deg[v]++; } Clean(n); l = 1, r = 0; for(register int i = 0; i < n; i++){ for(register int j = 1; j <= n; j++){ if(deg[j] == i){ if(i == 0) sum++; else q[++r] = j; } } if(!i) continue; while(l <= r){ int t = q[l]; l++; num[i].push_back(t); p[t].belong = i; sum++; for(register int k = head[t]; k; k = e[k].next){ int v = e[k].to; deg[v]--; if(deg[v] == i) q[++r] = v; } } l = 1, r = 0; if(sum == n){ now = i; break; } } for(register int i = now; i > 0; i--){ int len = num[i].size(); for(register int j = 0; j < len; j++){ int t = num[i][j]; for(register int k = head[t]; k; k = e[k].next){ int v = e[k].to; if(i < p[v].belong) Merge(t, v); else if(i == p[v].belong && t < v) Merge(t, v); } } for(register int j = 0; j < len; j++){ int t = num[i][j]; int f = Find(t); long long tmp = M * p[f].ms - N * p[f].ns + B * p[f].bs; if(ans2 < tmp){ ans1 = i; ans2 = tmp; } } } printf("%lld %lld", ans1, ans2); return 0; }
总结
这场难度应该算中等偏上吧,毕竟是 模拟赛,毕竟明天才是地狱试炼场级别的难度(事后诸葛亮了属于是)。
以下为博客签名,与博文无关。
只要你们不停下来,那前面就一定有我。所以啊,不要停下来~
本文来自博客园,作者:TSTYFST,转载请注明原文链接:https://www.cnblogs.com/TSTYFST/p/16596431.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理