第十四届蓝桥杯第二期模拟赛

问刚打完亚太再回来打场模拟赛的感觉(脑子已废)

周五刚出模拟赛成绩,顺便去OJ上测试了一下,以下代码确定AK


第一题

问题描述

  请找到一个大于 2022 的最小数,这个数转换成二进制之后,最低的 6 个二进制为全为 0 。
  请将这个数的十进制形式作为答案提交。

答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

没啥好说的,枚举一下即可

#include <bits/stdc++.h> using namespace std; int main() { int ans; for (int i=2023;;i++) { bool flag = false; for (int k=0;k<6;k++) { if (i>>k&1) { flag=true; continue; } } if (!flag) { ans=i; break; } } cout<<ans<<endl; return 0; }

第二题

问题描述

  我们计从 1949 年 10 月 1 日至 1949 年 10 月 2 日为经过了 1 天。
  请问从 1949 年 10 月 1 日至 2022 年 1 月 1 日经过了多少天?

答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

没啥好说的,典型的日期问题,这里分成两段感觉更好求解一些 26390

#include <bits/stdc++.h> using namespace std; int months[12] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30}; bool is_leapYear(int y) { return y % 400 == 0 || (y % 100 != 0 && y % 4 == 0); } int get(int y, int m, int d) { int res = d; for(int i = 1949; i < y; i ++) if(is_leapYear(i)) res += 366; else res += 365; for(int i = 1; i < m; i ++) res += months[i]; if(m > 2 && is_leapYear(y)) res ++; return res; } int main() { cout << get(2022, 1, 1) - get(1949, 10, 1) << endl; return 0; }

第三题

问题描述

  8518 是一个非常特殊的数,如果把这个数看成 16 进制数,它的值为 (8518)16=8161616+51616+116+8=34072,而 34072 正好是 8518 的整数倍。
  9558 也是这样一个数,当看成 16 进制时是 38232。
  其实长度为 1 的数 0 到 9 都满足看成 16 进制后是自己的整数倍(1倍)。
  请问,除开长度为 1 的数,最小的满足这样条件的数是多少?

答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

转16进制即可了,没啥好说的 ans:1038

#include <bits/stdc++.h> using namespace std; int res; int main() { for (int i=10;;i++) { int weight=1; int ans =0,sum=0; int temp=i; while (temp) { sum=temp%10; ans+=sum*weight; weight*=16; temp/=10; } if (ans%i==0) { res=i; break; } } cout<<res<<endl; return 0; }

第四题

问题描述
小蓝有一个 30 行 60 列的数字矩阵,矩阵中的每个数都是 0 到 9 之间的数字。
  174094882455171152761423221685761892795431233411387427793198
  650286024865090061389344606618496378829135984076361542097372
  601657541200146071777733599818266038012509478351201640618984
  143988087783837107349651099683484992553337438088068198972282
  890781586124258626539246182119762952003918195325258677229419
  698255491250839396799769357665825441616335532825361862146291
  503649293440596342887581257444442930778730382520372975343211
  325351222640703400531067500454956482168314849207060705673849
  265774579830223671554026061117300483012903885770893074783710
  083450145620356667677191627276513995926532444279237315785832
  411595106453089134746365281031552217482363035280722591085079
  053410485925413958279617719034175332412908745680774313630190
  429314820559328748143552689295945058801322270313370955837837
  939182801848609300876356583948397645861551964542532682663945
  625356614462682551015176002433628234343684739800880514363921
  982340231989891351425389287014819359798014755509282450440511
  590838726938103384801541373585690893606978941566666714061214
  952341523168827712604946036245881214982452998386986623826275
  782780208928205527678781609589000725521486468983551558405472
  149903035076783644195574734088152324666290493119955560594634
  905391288186024902215444250421277955403412298227858394469856
  607272647132163832860126054679347881638761723785858733108109
  249157334220127702410373959720286708183036202841837581704881
  367895556630088230650972282944827258473951902831431040790814
  079538232104075905120989173307660289899942087873076421916033
  622143260549608274076012938515668898707915863945382394851328
  164677964192631597026176253407553188801750590935427267220117
  591817866992665840378311257621611574856498432538327068011953
  631534031790352912617015229051836886166704989498756486878095
  690013558017746707412183571476823027885971347137127534455141
  现在小蓝想从这个矩阵的第一行第一列画一条折线到第 30 行 60 列,线只能沿水平向右走或竖直向下走,只能在有数字的地方拐弯。小蓝想知道,这样一条线经过的数字的和最大是多少。

答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

数字三角形的dp模型了,直接写吧 597

#include <bits/stdc++.h> using namespace std; const int N = 35,M = 65; int f[N][M]; char s[N][M]; int main() { for (int i=1;i<=30;i++) scanf("%s",s[i]+1); for (int i=1;i<=30;i++) for (int j=1;j<=60;j++) f[i][j]=max(f[i-1][j],f[i][j-1])+s[i][j]-'0'; cout<<f[30][60]<<endl; return 0; }

第五题

问题描述

  将 2022 拆分成不同的质数的和,请问最多拆分成几个?

答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

典型的0-1背包,先求出2022以内的质数,每个数看做一个价值和体积都是此数值的物品,总体积限制为正好是2022,求解最多能拿多少件物品? 33

#include <bits/stdc++.h> using namespace std; const int N = 2030; int f[N][N]; int primes[N]; int n; int cnt=1; bool isprime(int n) { for (int i=2;i<=n/i;i++) if (n%i==0) return false; return true; } int main() { for (int i=2;i<=2022;i++) if (isprime(i)) primes[cnt++]=i; for (int i=1;i<cnt;i++) for (int j=2;j<=2022;j++) { if (primes[i]>j) f[i][j]=f[i-1][j]; else f[i][j]=max(f[i-1][j],f[i-1][j-primes[i]]+1); } cout<<f[cnt-1][2022]<<endl; return 0; }

第6题

问题描述

  小蓝正在拷贝一份文件,他现在已经拷贝了 t 秒时间,已经拷贝了 c 字节,文件总共有 s 字节,如果拷贝是匀速进行的,请问小蓝大概还需要拷贝多少秒?
输入格式
  输入一行包含三个整数 t, c, s,相邻两个整数之间用一个空格分隔。
输出格式
  输出一个整数,表示答案。数据保证答案正好是整数。
样例输入

3 10 20

样例输出

3

样例输入

30 14 21

样例输出

15

评测用例规模与约定
  对于 50% 的评测用例,1 <= t, c, s <= 10000。
  对于所有评测用例,1 <= t, c, s <= 1000000000

没啥好说的,签到题

#include <bits/stdc++.h> using namespace std; int main() { int t,c,s; scanf("%d%d%d", &t, &c, &s); printf("%lld\n", (s - c) * 1ll * t / c); return 0; }

第7题

问题描述

  小蓝有 n 个单词,但是单词中有一些是重复的,请帮小蓝去除重复的单词。
输入格式
  输入第一行包含一个正整数 n ,表示小蓝的单词数量。
  接下来 n 行,每行包含一个由小写字母组成的单词。
输出格式
  请输出去除重复后的那些单词。如果一个单词出现了多遍,请保留第一次出现的单词,去除之后出现的单词,按输入的顺序输出。
样例输入

5 lanqiao hi hello hello lanqiao

样例输出

lanqiao hi hello

评测用例规模与约定
  对于所有评测用例,1 <= n <= 100,每个单词的长度不超过 100。

哈希表即可实现(这里用的unordered_map,unordered_set会更好~)

#include <bits/stdc++.h> using namespace std; const int N = 110; vector<string>V; int n; unordered_map<string,int>h; int main() { cin>>n; while (n--) { string s; cin>>s; h[s]++; if (h[s]==1) V.push_back(s); } for (auto v:V) cout<<v<<endl; return 0; }

第8题

问题描述

  一个字符串如果从左向右读和从右向左读相同,则称为一个回文串,例如 lanqiaoaiqnal 是一个回文串。
  小蓝有一个字符串,请将这个字符串右边加上一些字符,使其成为一个回文串。
  如果有多种方案,请输出最短的回文串。
输入格式
  输入一行包含一个字符串,由小写英文字母组成。
输出格式
  输出一行包含答案。
样例输入

lanqiao

样例输出

lanqiaoaiqnal

样例输入

banana

样例输出

bananab

样例输入

noon

样例输出

noon

评测用例规模与约定
  对于所有评测用例,1 <= 字符串长度 <= 100。


因为只能在字符串右侧(也就是结尾)添加字符,使得原字符串变为回文串。而且每个字符串的长度只有100,即可从左往右暴力枚举,直到当前位置之后的字符串是回文串了,记录从头到此处的子串,此时就可以在末尾添加子串。

#include <bits/stdc++.h> using namespace std; const int N = 110; string s,t; bool ishuiwen(string x) { int i =0,j=x.size()-1; while (i<j) { if (x[i]!=x[j]) { return false; } else i++,j--; } return true; } int main() { cin>>s; for (int i=0;i<s.size();i++) { string temp = s.substr(i,s.size()); if (ishuiwen(temp)) { t = s.substr(0,i); break; } } reverse(t.begin(),t.end()); string ans = s+t; cout<<ans<<endl; return 0; }

第9题

第九题

问题描述

  给定一个字母矩阵。一个 X 图形由中心点和由中心点向四个45度斜线方向引出的直线段组成,四条线段的长度相同,而且四条线段上的字母和中心点的字母相同。
  一个 X图形可以使用三个整数 r, c, L 来描述,其中 r, c 表示中心点位于第 r 行第 c 列,正整数 L 表示引出的直线段的长度。 对于 1 到 L 之间的每个整数 i,X图形满足:第 r-i 行第 c-i 列与第 r 行第 c 列相同,第 r-i 行第 c+i 列与第 r 行第 c 列相同,第 r+i 行第 c-i 列与第 r 行第 c 列相同,第 r+i 行第 c+i 列与第 r 行第 c 列相同。
  例如,对于下面的字母矩阵中,所有的字母 L 组成一个 X图形,其中中间的 5 个 L 也组成一个 X图形。所有字母 Q 组成了一个 X图形。
  LAAALA
  ALQLQA
  AALQAA
  ALQLQA
  LAAALA
  给定一个字母矩阵,请求其中有多少个X图形。
输入格式
  输入第一行包含两个整数 n, m,分别表示字母矩阵的行数和列数。
  接下来 n 行,每行 m 个大写字母,为给定的矩阵。
输出格式
  输出一行,包含一个整数,表示答案。
样例输入

5 6 LAAALA ALQLQA AALQAA ALQLQA LAAALA

样例输出

3

评测用例规模与约定
  对于 50% 的评测用例,1 <= n, m <= 10
  对于所有评测用例,1 <= n, m <= 100

一看如此小的数据规模,暴力枚举就完了hhh

1. 先枚举所有可能作为x图形中心的顶点位置
2. 再枚举x图形可能的高度,即从1到(n-1)/2
3. 检验x图形是否满足要求,即对应位置的字符等于中心顶点的字符

#include <bits/stdc++.h> using namespace std; const int N = 110; typedef pair<int,int>PII; #define x first #define y second int n,m; char s[N][N]; int ans; bool check(char c,PII p,int k) // 判断是否符合x图形的要求 { bool flag=false; for (int i=1;i<=k;i++) { if (s[p.x-i][p.y-i]!=c||s[p.x-i][p.y+i]!=c||s[p.x+i][p.y-i]!=c||s[p.x+i][p.y+i]!=c) flag = true; } if (flag) return false; return true; } int main() { cin>>n>>m; for (int i=0;i<n;i++) cin>>s[i]; for (int i=1;i<n-1;i++) for (int j=1;j<m-1;j++) // 枚举可能的顶点 { char c = s[i][j]; PII p = {i,j}; for (int k=1;k<=(n-1)/2;k++) // 枚举x图形可能的高度L { if (p.x-k<0||p.x+k>n||p.y-k<0||p.y+k>m) continue; // 越界特判 if (check(c,p,k)) ans++; } } cout<<ans<<endl; return 0; }

第10题

问题描述

  小蓝有一个序列 a[1], a[2], ..., a[n],每次可以交换相邻的两个元素,代价为两个元素中较大的那个。
  请问,要通过交换将序列变为从小到大递增的序列,总代价最少为多少?
输入格式
  输入一行包含一个整数 n ,表示序列长度。
  第二行包含 n 个整数,表示给定的序列。
输出格式
  输出一行包含一个整数,表示最少代价的值。
样例输入

4 1 5 2 1

样例输出

12

评测用例规模与约定
  对于 30% 的评测用例,1 <= n <= 1000, 1 <= a[i] <= 1000。
  对于 60% 的评测用例,1 <= n <= 50000, 1 <= a[i] <= 50000。
  对于所有评测用例,1 <= n <= 1000000, 1 <= a[i] <= 1000000

归并排序的板子,只不过这里不是求解逆序对的数量,而是求每个逆序对中较大的那个值的和。因为最后是要求非严格的递增序列,因此一定不会存在逆序对,那么就可以通过不断交换逆序对中的两个元素,来实现序列递增的效果。

#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N = 100010; int q[N],t[N]; long long merge_sort(int l,int r) { if (l>=r) return 0; int mid=l+r>>1; long long ans=merge_sort(l,mid)+merge_sort(mid+1,r); int k=0; int i=l,j=mid+1; while (i<=mid&&j<=r) { if (q[i]<=q[j]) t[k++]=q[i++]; else { t[k++]=q[j++]; for (int k=i;k<=mid;k++) ans+=q[k]; // ans为求解i~mid的数值之和 } } while (i<=mid) t[k++]=q[i++]; while (j<=r) t[k++]=q[j++]; for (int i=l,j=0;i<=r;i++,j++) q[i]=t[j]; return ans; } int main() { int n; cin>>n; for (int i=0;i<n;i++) cin>>q[i]; cout<<merge_sort(0,n-1)<<endl; return 0; }

总结

感觉这次的模拟赛多了些dp题,题目的质量比上期好一些。还是有很大收获的,还是太菜了些唉,加油冲~


__EOF__

本文作者dfl
本文链接https://www.cnblogs.com/sdnu-dfl/p/16931823.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   勇敢龙龙  阅读(1950)  评论(8编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示