2021年第12届蓝桥杯国赛做题记录
A:带宽:计算200Mbps=?MB/s。常识题,答案200/8=25
先打一个素数表,然后遍历即可。答案1903
bool check(int n):
while (m > 0) {
int i = m % 10;
if (i != 2 && i != 3 && i != 5 && i != 7)
return 0;
m /= 10;
}
return 1;
int main():
int n=20210605,res=0;
int k=init(n);
for (int i = 0; i < k; i++) {
if (check(p[i])) {
//printf("%d\n",i);
res++;
}
}
暴力即可。可以写一个简单的日期类。答案977
bool check(Date d) {
string s=d.toString();
int x=0;
for(char c:s) x+=c-'0';
int y=(int)sqrt(x);
//if(y*y==x) printf("%d\n",x);
return y*y==x;
}
main:
while(!(now==end)) {
if(check(now)) {
res++;
//puts(now.toString().c_str());
}
now=now.next();
}
不会
E:小写转大写:送分题,s[i]=s[i]-'a'+'A'
思路1:约定f(x)=(x*(x+1))/2。不难得出前p段的数字个数等于第p段所有数字的和。
首先由等差数列求和公式算出和分别位于哪一段。(可用二分法)如果位于相同的段则要特别处理,(这点以后一定要注意)。
否则,假设二者分别位于pl与pr段,则(pl,pr)之间的段都可以用f(i)直接算出来,
再算出第l个数在pl段中是第几个(也就是算出第l个数的值,假设为left),办法是算出前pl-1段有多少个(即f(pl-1)),用l-left即得;最后计算f(pl)-f(left)即可
同理算出第r个数在pr段中是第几个。这种方法对应70%数据。
inline int part(llong i) {
int p=1;
int l=1,r=1e7;
while(l<r) { //二分查找,相当于lower_bound
p=(l+r)/2; //假设第p段
llong st=calc(1,p-1)+1; //计算第p段第一项
if(st>i) { //如果i于st,则说明答案在右半段
r=p;
}
else {
l=p+1;
}
}
return l-1;
}
int main() {
//省略输入
while(t--) {
llong l,r,res=0;
scanf("%lld%lld",&l,&r);
int par_l=part(l),par_r=part(r); //计算二者是在哪段
//printf("%d %d\n",par_l,par_r);
for(int i=par_l+1; i<par_r; i++) {
res+=calc(1,i);
}
llong left=l-calc(1,par_l-1),right=r-calc(1,par_r-1); //单独处理“左边距”与“右边距”
if(par_l!=par_r) {
res+=calc(left,par_l)+calc(1,right);
}
else {
res+=calc(left,right);
}
printf("%lld\n",res);
}
}
思路2:针对main()中for循环,可在思路1的基础上推公式。可过全部数据。
个人觉得这种题适合出在蓝桥杯中,毕竟很多解法都能拿部分分。
方法1:暴力,能过40%
方法2:找循环节,把循环节存下来。但不排除爆空间风险。能过>=80%
char tt[M]; //使用char[]提高性能
int main() {
NO_SYNC;
int n;llong t;
cin>>n>>t;
string s,org;
cin>>s;
org=s;
strs.reserve(n);
strs.push_back(org);
do {
tt[0]=s[0];
for(int i=1; i<n; i++) {
tt[i]= (char)((s[i]-'0')^(s[i-1]-'0'))+'0';
}
s=tt;
strs.push_back(s);
} while(s!=org);
strs.pop_back();
cout<<strs[t%strs.size()];
}
若最高位为0,则只要在低位中取k个1即可。这部分可利用组合数公式。
最高位为1,符合条件的最小数为100....11b(共t位,有k个1,除最高位外的k-1个1均在最低位连续排列)最大为min(n,111....00b)(共t位前K个为1)。只要遍历这部分数即可。如果利用__builtin_popcount
复杂度大约。虽然还是过不了,不过数据出的好的话能混60%。
当然,考场上为节约时间这部分就不要考虑什么最小数最大数了。虽然可能少几分但有时间做别的题目。
正解数位DP,详参:https://blog.csdn.net/As_zyh/article/details/117637080
不会,但应该属于RMQ问题,可以设左括号为0,右括号为1,用线段树或分块说不定可行。
首先a ^ b ^ c == 0-->a ^ b == c,由异或的定义知这个式子的三个数可以任意互换位置。因此只要算出a<b<c时的结果*6即可。
这里还有一个优化:设f[i]=,则对任意的i,若j<f[i]则不可能有i ^ j > j,因此从f[i]开始遍历即可。
同上,考试时节约时间就不要往这上想了。反正不太可能会多一分。
自己做能有5+5+10+15+10+16+6+5=72分,在考场上就不知道能怎样了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律