2025“钉耙编程”中国大学生算法设计春季联赛(2)

news/2025/3/18 22:33:06/文章来源:https://www.cnblogs.com/watersail/p/18774711

学历史导致的

  • 真心没必要专门写个程序给字符串加引号呀
#include <bits/stdc++.h>
using namespace std;
const string tian[]={"jia","yi","bing","ding","wu","ji","geng","xin","ren","gui"};
const string di[]={"zi","chou","yin","mao","chen","si","wu","wei","shen","you","xu","hai"};
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){string s;cin>>s;int p=0,q=0;int y=1984;while(1){if(tian[p]+di[q]==s){break;}p=(p+1)%10;q=(q+1)%12;y++;}cout<<y<<"\n";}return 0;
}

学 DP 导致的

  • 提交之前多看两眼呀。直面结果不是急切和无所谓,而是敬畏和自信才对
#include <bits/stdc++.h>
using namespace std;
int f[3005],cnt[30];
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){string s,t;cin>>s>>t;memset(cnt,0,sizeof(cnt));for(char c:s){cnt[c-'a']++;}int ans=0;for(int i=0;i<26;i++){ans=ans+(cnt[i]>0);}if(t.size()>2){cout<<ans<<endl;continue;}int k;if(t.size()==2){k=10*(t[0]-'0')+(t[1]-'0');}else{k=t[0]-'0';}if(k>=26){cout<<ans<<endl;continue;}t="";while(k--){t+=s;}ans=0;for(int i=0;i<t.size();i++){f[i]=1;for(int j=0;j<i;j++){if(t[j]<t[i]){f[i]=max(f[i],f[j]+1);}}ans=max(ans,f[i]);}cout<<ans<<endl;}return 0;
}

学数数导致的

  • 注意break和continue的作用范围,后面做计算那道题的时候也遇到这个问题
#include <bits/stdc++.h>
using namespace std;
int a[1000005],cnt[1000005],tag[1000005];
vector<int>c[1000005];
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){int n;cin>>n;for(int i=1;i<=n;i++){cin>>a[i];cnt[a[i]]=0;c[a[i]].push_back(i);}int p=0;long long ans=0;for(int i=1;i<=n;i++){if(a[i]&&c[a[i]].size()){while(p<c[0].size()&&c[0][p]<i){p++;}if(p==c[0].size()){c[a[i]].clear();continue;}int q=c[0][p];int w=upper_bound(c[a[i]].begin(),c[a[i]].end(),q)-c[a[i]].begin();if(w==c[a[i]].size()){c[a[i]].clear();continue;}tag[c[a[i]][w]+1]++;c[a[i]].clear();}}c[0].clear();tag[n+1]=0;long long cur=0;for(int i=n;i>=1;i--){if(a[i]&&!cnt[a[i]]){cur++;}cnt[a[i]]++;ans=ans+cur*tag[i];tag[i]=0;}cout<<ans<<endl;}return 0;
}

学博弈论导致的

  • 经典结论:Bash 游戏
  • n 颗石子,每次至多取 m 颗,当且仅当 m+1 | n 时先手必败(后手和先手共同取走 m+1 颗即可)
  • 假设红宝石1元钱,蓝宝石2元钱,宝盒4元钱,那么问题完全等价于:桌上有r+2b+4m元钱,Alice, Bob 轮流取钱,每次可以取 1~3 元,问最后谁胜
  • 认真分析了一会儿,也是很快猜出结论了~
#include <bits/stdc++.h>
using namespace std;
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){int r,b,m;cin>>r>>b>>m;if(b%2==0){if(r%4==0){cout<<"Bob\n";}else{cout<<"Alice\n";}}else{if(r%4==2){cout<<"Bob\n";}else{cout<<"Alice\n";}}}return 0;
}

学画画导致的

  • 其实这道题是一道阅读理解题。你以为你读懂题目了,其实你只是读懂了题目的形式,而没有理解题目的本质。而当你沉下心来,再读一遍题目之后,做法自然水落石出
#include <bits/stdc++.h>
using namespace std;
struct t1
{int x,y,c;
}t[300005];
vector<int>a[900005];
int d[900005],tot;
void topsort(int n)
{queue<int>q;for(int i=1;i<=3*n;i++){if(d[i]==0){q.push(i);}}while(q.size()){int n1=q.front();q.pop();tot++;for(int i=0;i<a[n1].size();i++){d[a[n1][i]]--;if(d[a[n1][i]]==0){q.push(a[n1][i]);}}}
}
void add(int u,int v)
{if(u!=v){a[u].push_back(v);d[v]++;}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){int n,m;cin>>n>>m;for(int i=1;i<=3*n;i++){a[i].clear();d[i]=0;}tot=0;for(int i=1;i<=m;i++){cin>>t[i].x>>t[i].y>>t[i].c;}bool ans=true;for(int i=1;i<=m;i++){int x=(t[i].y+1)/2;int y=2*n+1-t[i].x;int z=2*n+t[i].x-t[i].y/2;if(x!=t[i].c&&y!=t[i].c&&z!=t[i].c){ans=false;break;}else{add(t[i].c,x);add(t[i].c,y);add(t[i].c,z);}}if(ans==false){cout<<"No\n";continue;}topsort(n);if(tot==3*n){cout<<"Yes\n";}else{cout<<"No\n";}}return 0;
}

其实下面的三道题都在你的能力范围内,如果专心做其中任何一道,我想你都能做出来。可是在赛场上,同时面对这三道题目,“乱花渐欲迷人眼”,你难免优柔寡断,担心选错方向而不敢全力以赴。


学排列导致的

  • 赛场上也想过用线段树维护,但很快就自我否定了。为什么呢?对每个线段树节点维护1个大小为30的数组,空间已经吃紧了吧,开30个怎么可能开得下呢?可是,由于你要存的数都在30以内,完全可以用char类型存,然后再用动态开点线段树的方法省掉一倍空间,算一下就会发现,\(200000*30*30/1024/1024*2=343.3MB\),完全开得下呀!
  • 注意到\(\circ\)有结合律,因此直接用线段树维护
  • 直接求逆排列的思维太反直觉了,顺应自己的直觉,用逆元的方法求逆排列,记\(s_i=p_1\circ p_2\circ ...\circ p_i\),然后有\(s_{l-1}\circ p_l\circ p_{l+1} \circ ...\circ p_r=s_r\),于是\(p_l\circ p_{l+1} \circ ...\circ p_r=(s_{l-1})^{-1}\circ s_r\)
  • 给定\(1\sim n\)的一个排列和它的每个元素的排名的序列,就互为逆排列
  • 本题有大量置换,尝试把它封装成一个模块以简化编程复杂度:事先写一个结构体perm,重载u*v运算并实现求逆元
  • 注意标记为0时不能下传。虽然对修改没有影响,但是会覆盖原来的标记。怀揣找出错误的渴望,很快就能发现程序的问题所在呢
#include <bits/stdc++.h>
using namespace std;
unsigned long long Seed;
unsigned myrand(){Seed^=Seed>>5;Seed^=Seed<<3;return Seed;}
//template< typename T >void swap(T u,T v){T t=u;u=v;v=t;} //如选手未调用 algorithm 库,请取消注释本行
template< typename T >void generate(int k,T p[]){//k 为题目中的 k,p[] 为产生的排列存储位置,下标从 1 开始auto *q=p+1;for(int i=1;i<=k;i++)p[i]=i;for(int i=k-1;i>0;i--)swap(q[i],q[myrand()%i]);
}
int n,m,k;
struct perm
{char p[30+1];perm(){iota(p+1,p+k+1,1);}perm inv(){perm res;for(int i=1;i<=k;i++){res.p[p[i]]=i;}return res;}
};
perm operator *(perm a,perm b)
{perm c;for(int i=1;i<=k;i++){c.p[i]=a.p[b.p[i]];}return c;
}
struct t1
{int l,r,bj;perm k[30+1];
}t[400005];
int tot;
int build(int p,int l,int r)
{if(!p){p=++tot;t[p].bj=0;}if(l==r){generate(k,t[p].k[0].p);for(int i=1;i<=k;i++){for(int j=1;j<=k;j++){t[p].k[t[p].k[0].p[i]].p[j]=t[p].k[0].p[(i+j-2)%k+1];}}return p;}int mid=(l+r)>>1;t[p].l=build(0,l,mid);t[p].r=build(0,mid+1,r);t[p].k[0]=t[t[p].l].k[0]*t[t[p].r].k[0];for(int i=1;i<=k;i++){t[p].k[i]=t[t[p].l].k[i]*t[t[p].r].k[i];		}return p;
}
void spread(int p)
{if(t[p].bj){t[t[p].l].bj=t[p].bj;t[t[p].r].bj=t[p].bj;t[t[p].l].k[0]=t[t[p].l].k[t[p].bj];t[t[p].r].k[0]=t[t[p].r].k[t[p].bj];t[p].bj=0;}
}
perm ask(int p,int l,int r,int u,int v)
{if(u>v){return *new perm;}if(u<=l&&v>=r){return t[p].k[0];}spread(p);int mid=(l+r)>>1;perm res;if(u<=mid){res=res*ask(t[p].l,l,mid,u,v);}if(v>mid){res=res*ask(t[p].r,mid+1,r,u,v);}return res;
}
void change(int p,int l,int r,int u,int v,int z)
{if(u<=l&&v>=r){t[p].k[0]=t[p].k[z];t[p].bj=z;return;}spread(p);int mid=(l+r)>>1;if(u<=mid){change(t[p].l,l,mid,u,v,z);}if(v>mid){change(t[p].r,mid+1,r,u,v,z);}t[p].k[0]=t[t[p].l].k[0]*t[t[p].r].k[0];
}
void output(perm x)
{for(int i=1;i<=k;i++){cout<<(int)x.p[i]<<" ";}cout<<endl;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cin>>n>>m>>k>>Seed;build(0,1,n);for(int i=1;i<=m;i++){int op,l,r,z;cin>>op>>l>>r>>z;if(op==1){perm ans=ask(1,1,n,1,l-1).inv()*ask(1,1,n,1,r);cout<<(int)ans.p[z]<<"\n";}else{change(1,1,n,l,r,z);}}return 0;
}

学位运算导致的

  • 1e16的本质是科学计数法,而科学计数法的本质是浮点数,用在1e16这样的大整数上会导致精度误差【之前还奇怪为什么1e运算扩展到long long范围时不用加标识符呢】
  • 其实这道题你几乎都想出正解了呀,可还是自我否定了,为什么呢?因为用到了最“值”的方法,之前做某道位运算题的时候你也用到了最“值”,事后证明是错解。但这道题给了你一个完备集,正解就是求最“值”呀。包括上一题也是。由此可见,你之前认为是错误的很多想法其实并非毫无价值,只是没有出现在正确的位置。因此,你不应该囿于过往的经验,而应该在经验的基础上理性分析
  • \(a\& b \le min(a,b)\) \(a|b \ge max(a,b)\)
#include <bits/stdc++.h>
using namespace std;
#define int unsigned long long
int a[500005];
signed main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){int n,q;cin>>n>>q;int s[64]={0};fill(s,s+64,0ull-1);for(int i=1;i<=n;i++){cin>>a[i];for(int j=0;j<64;j++){if((a[i]>>j)&1){s[j]=s[j]&a[i];}}}int res=0;for(int i=1;i<=q;i++){int x;cin>>x;int ans=0ull-1,cur=0;for(signed j=63;j>=0;j--){if(((x>>j)&1)==0){ans=min(ans,cur|s[j]);}else{cur=cur|s[j];}}ans=min(ans,cur);res=(res^(ans%10000000000001029ll));}cout<<res<<"\n";}return 0;
}

学计算导致的

  • 虽然你看到这个题就觉得是DP,题解的标签也是DP,从本质上讲似乎也可以说它是DP,但由于DP在你的刻板印象里与倒推的思维方式绑定,因此对你而言,还是用【记忆化搜索遍历状态空间】概括这道题的解法更加妥帖
  • 用sum, mul, cur分别表示已经结束的所有项之和、当前项的乘数, 以及当前要计算的数字
  • 也可以根据数据范围推一下做法,特别是数据小的时候。(nm)^2 很难再加一个 k,nmk^2 还有空余,所以很可能是 nmk^3
  • 状态压缩可以这样写:
int enc(int sum,int mul,int cur)
{return (sum*k+mul)*k+cur;
}
  • ASCII码最大到127,可以通过预处理出每个状态的后继状态构建自动机,既降低编程复杂度也优化常数
  • 用BFS实现提交一直超时,不知何故
#include <bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int n,m,k;
char c[101][101];
int f[101][101][8000];
int tr[128][8000];
int enc(int sum,int mul,int cur)
{return (sum*k+mul)*k+cur;
}
void add(int &x,int y)
{x+=y;if(x>=mod){x-=mod;}
}
void dp()
{f[1][1][enc(0,1,(c[1][1]-'0')%k)]=1;for(int x=1;x<=n;x++){for(int y=1;y<=m;y++){for(int s=0;s<k*k*k;s++){int val=f[x][y][s];if(x+1<=n){char ch=c[x+1][y];int u=x+1,v=y,t=tr[ch][s];if(isdigit(c[x][y])||isdigit(ch)){add(f[u][v][t],val);}	}if(y+1<=m){char ch=c[x][y+1];int u=x,v=y+1,t=tr[ch][s];if(isdigit(c[x][y])||isdigit(ch)){add(f[u][v][t],val);}}}}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);int T;cin>>T;while(T--){memset(f,0,sizeof(f));cin>>n>>m>>k;for(int sum=0;sum<k;sum++){for(int mul=0;mul<k;mul++){for(int cur=0;cur<k;cur++){for(int ch='0';ch<='9';ch++){tr[ch][enc(sum,mul,cur)]=enc(sum,mul,(cur*10+ch-'0')%k);}tr['+'][enc(sum,mul,cur)]=enc((sum+mul*cur)%k,1,0);tr['-'][enc(sum,mul,cur)]=enc((sum+mul*cur)%k,k-1,0);tr['*'][enc(sum,mul,cur)]=enc(sum,mul*cur%k,0);}}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>c[i][j];}}dp();int ans=0;for(int sum=0;sum<k;sum++){for(int mul=0;mul<k;mul++){for(int cur=0;cur<k;cur++){if((sum+mul*cur)%k==0){add(ans,f[n][m][enc(sum,mul,cur)]);}}}}cout<<ans<<endl;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/901148.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web154-web156笔记(图片内容过滤php-短标签形式转换)

继续按照上题步骤,传一个.user.ini文件,接着在上传图片马的时候报错了 解码后显示的文字是不支持格式,说明可能内容里的php被ban了,改成短标签的形式再上传,而且末尾不能有php,做任意匹配,可以通过 短标签形式:<?=system("tac ../f*");?> 原来…

Netty基础—8.Netty实现私有协议栈

大纲 1.私有协议介绍 2.私有协议的通信模型 3.私有协议栈的消息定义 4.私有协议栈链路的建立 5.私有协议栈链路的关闭 6.私有协议栈的心跳机制 7.私有协议栈的重连机制 8.私有协议栈的重复登录保护 9.私有协议栈核心的ChannelHandler 10.私有协议栈的客户端和服务端 11.私有协议…

10. PWM输出

一、PWM简介PWM(Pulse Width Modulation),简称脉宽调制,是一种将模拟信号变为脉冲信号的计数。PWM 可以控制 LED 亮度、直流电机的转速等。PWM 的主要参数如下:PWM 频率。PWM 频率是 PWM 信号在 1s 内从高电平到低电平再回到高电平的次数,也就是说 1s 内有多少个 PWM 周期…

memcached DRDOS攻击实验

memcached DRDOS攻击实验 一、前提 关于drdos DRDoS(Distributed Reflection Denial of Service) 指的是利用IP Spoofing技术,构造带有受害者IP的数据包,发送给肉鸡,然后肉鸡对受害者IP做出大量回应,造成拒绝服务。 关于memcached命令 第一个是上传有效载荷Memcached set 命…

USB分类

USB特点差分传输 差错管理 恢复机制协议标准左边是原标准,后面是新标准USB1.1:低速、全速 USB2.高速 USB3.0 8b/10b编码 增加一对超高速差分线 USB3.1 采用 128b/132b编码,速度提升一倍 USB3.2 增加一对超高速传输通道,速度再次翻倍,只在C口上运行速度等级1.5Mbps/12M/480M…

0318- Wifi模式选择,信道选择

前言 在设置 H3C 路由器的时候(管理地址居然不是192.168.0.1,而是 http://192.168.124.1/),我发现 有下面的3种设置无线模式 无线频宽 无线信道Wifi 模式选择 推荐 n-only 也就是 Wifi-4 及以上的协议模式 其他的都是古早协议了,如果家里没有那种老设备就完全不需要考虑兼容…

20244214 实验一《Python程序设计》实验报告

20244214 2024-2025-2 《Python程序设计》实验一报告 课程:《Python程序设计》 班级: 2442 姓名: 张家乐 学号:20244214 实验教师:王志强 实验日期:2025年3月18日 必修/选修: 公选课 1.实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练…

日报2025318

今日学习Element-plus组件 首先供上我们的element plus 行为指导库 https://element-plus.org/zh-CN el-button<div><el-button color="rgb(247, 137.4, 137.4)" plain style="color: white" > Komeigi Satori</el-button></div>…

BP算法

反向传播算法,简称BP算法,是多层神经元网络常用的学习算法之一,它建立在梯度下降算法的基础上。BP算法的完整学习过程由正向传播过程和反向传播过程组成。反向传播的过程是利用梯度下降算法,最小化代价函数 的过程。假设使用如图2.1所示的神经网络,该网络有一个输出层、两…

基于GA遗传算法的拱桥静载试验车辆最优布载matlab仿真

1.程序功能描述 基于GA遗传算法的拱桥静载试验车辆最优布载matlab仿真。主要是为了实现桥梁静载试验自动化布载(确定车辆位置使得满足加载效率ηq的要求,0.95≤ηq≤1.05),总体要求是ηq尽量靠近1,所用的加载车辆尽量少,进行布载耗时越少越好。 2.测试软件版本以及运…

攻防世界 guess_num WriteUp

WriteUp 题目信息 来源:攻防世界 名称:guess_num 分类:Pwn 描述:菜鸡在玩一个猜数字的游戏,但他无论如何都银不了,你能帮助他么题目链接: https://adworld.xctf.org.cn/challenges/list解题思路 首先使用DIE对文件进行查壳,发现这是一个无壳的64位ELF文件。于是直接使用…