当前位置: 首页 > news >正文

ICPC Central Russia Regional Contest, 2024 补题

作为校内选拔赛打的 链接

I 图 暴力

一开始没有把实现细节想好,把身子当成环走的话,可能误入歧途到鱼头里。
尾巴和头当环遍历,身子是两条链。走过的地方标记vis=1,防止回头路。
在这里插入图片描述

const int N=1e5+10,C=1e2+10;
vector<int>e[N];
int deg[N];
int vis[N];
int f,t[2]={0,0};//f:有4个分量的点 three:有3个分量的点
int bd,tl,hd;//body tail head
void solve(){int n;cin>>n;forr(i,1,n+2){int a,b;cin>>a>>b;e[a].push_back(b);e[b].push_back(a);deg[a]++,deg[b]++;}int id=0;forr(i,1,n){if(deg[i]==4)f=i;if(deg[i]==3)t[id++]=i;}// cout<<f<<' '<<t[0]<<' '<<t[1]<<endl;// 身 尾 从deg=4的点出发vis[f]=1;for(auto x:e[f]){if(vis[x]==0){int now=x,cnt=1,fg=0;while (now!=f){if(now==t[0]||now==t[1]){//身子走到deg=3的点就跳出fg=1;break;}cnt++;int tp=0;vis[now]=1;for(auto x:e[now]){if(vis[x]==0){tp=1;now=x;break;}}if(tp==0)now=f;//没有vis=0的点可走了 成环回到f点}if(fg==1){bd+=cnt;}else tl+=cnt;}}bd++;// 只剩下头forr(i,1,n)hd+=(vis[i]==0);cout<<hd<<' '<<bd<<' '<<tl<<endl;
}

以下题目补题思路参考

C 数学 思维 位运算

r=(2n+2m)kr=(2^n+2^m)^kr=(2n+2m)k的二进制位1的个数
r=2k⋅min(m,n)(1+2∣n−m∣)kr=2^{k\cdot min(m,n)}(1+2^{|n-m|})^kr=2kmin(m,n)(1+2nm)k
2k⋅min(m,n)2^{k\cdot min(m,n)}2kmin(m,n)的移位对1的个数无影响,主要看(1+2∣n−m∣)k=∑i=0kCki2i⋅∣n−m∣(1+2^{|n-m|})^k=\sum_{i=0}^{k}C_k^i2^{i\cdot|n-m|}(1+2nm)k=i=0kCki2inm

void solve(){int n,m,k;cin>>n>>m>>k;if(n==m)return cout<<1<<endl,void();int d=abs(n-m);int ans=0;if(d>=100){//k<=100 不会有重叠//二项式定理 是对组合数的移位vector<llint>c(k+1,0);c[0]=1;forr(i,1,k)c[i]=c[i-1]*(k-i+1)/i;forr(i,0,k){llint num=c[i];int cnt=0;while (num>0){cnt+=(num&1);num>>=1;}ans+=cnt;}}// 一开始想组合数移位故技重施 // else{//     int rg=d*k+100;//     vector<int>bits(rg,0);//     vector<llint>c(k+1,0);//     c[0]=1;//     forr(i,1,k)c[i]=c[i-1]*(k-i+1)/i;//     bits[0]=1;//     forr(i,1,k){//         int j=0,num=c[i];//         while (num>0)//         {//             bits[i*d+j]+=(num&1);//             num>>=1;//             j++;//         }//     }//     // forr(i,1,k)cout<<c[i]<<' ';cout<<endl;//     int tp=0;//     for(auto &x:bits){//         x+=tp;//         ans+=(x&1);//         tp=x/2;//     }// }else{//乘k次(2^d+1) 相当于所有的数每次再加移位d位的数 //直接移位会溢出 需要一位位找int rg=d*k+130;vector<int>bits(rg+1,0);bits[0]=1;forr(i,1,k){int tp=0;vector<int>tp_bits(rg+1,0);//要从上一个转移下来 保留原来的forr(j,0,rg){int now=bits[j];//原来的now+=tp;//加进位if(j>=d)now+=bits[j-d];//前面的移位过来tp_bits[j]=(now&1);tp=now/2;}bits=tp_bits;}for(auto x:bits)ans+=x;}cout<<ans<<endl;
}

N dp

const int N=5e4+10,mod=1e9+9,inf=3e3;
void solve(){int n;cin>>n;vector<string>nm(n+1);forr(i,1,n){cin>>nm[i];}string aim=nm[1];int l=aim.size();vector<int>len;//记录和每个名字公共前缀长度forr(i,1,n){int cmn=0;forr(j,0,min(l,(int)nm[i].size())-1){if(nm[i][j]==aim[j])cmn++;else break;}len.push_back(cmn);}sort(len.begin(),len.end());vector<int>pxlen(l+1);forr(i,0,l){//i是一个个输入的长度 auto px=lower_bound(len.begin(),len.end(),i);//要在所有前缀中找大于等于i的前缀长度 前缀长度<i就可能会和其他前缀区分不出来//pxlen是一个个打到i个字符的时候 按tab后能达到的长度if(px==len.end())pxlen[i]=l;else pxlen[i]=(*px);}// forr(i,0,l)cout<<pxlen[i]<<' ';cout<<endl;vector<int>dp(l+1,inf);//dp[i] 输入i长度需要最小操作数dp[0]=0;//两种转移:1.前面的+1 2.前面的某个位置按tab拓展//拓展:达到i个字符 每个数向后转移//所以转移直接遍历前面的 转移到后面的forr(i,0,l){if(i<l)dp[i+1]=min(dp[i+1],dp[i]+1);//一个个打if(pxlen[i]>i)dp[pxlen[i]]=min(dp[pxlen[i]],dp[i]+1);//按tab// forr(j,0,l)cout<<dp[j]<<' ';cout<<endl;}cout<<dp[l]<<endl;
}

G 启发式合并

unordered_map<int,int>cnt;
vector<pair<int,int>>e[N];
int deg[N],c[N],ans[N];
int cal_sz(int now){int sz=1;for(auto &[xsz,x]:e[now]){xsz=cal_sz(x);sz+=xsz;}sort(e[now].rbegin(),e[now].rend());//计算子树大小 首要对大小进行排序 先处理小的return sz;
}
unordered_map<int,int> dfs(int now){//返回颜色列表if(e[now].size()==0){ans[now]=c[now];return {{c[now],1}};}unordered_map<int,int>c_mp=dfs(e[now][0].second);//创建属于该点的颜色列表int mx=ans[e[now][0].second];//本节点答案 从子节点转移过来forr(i,1,e[now].size()-1){int x=e[now][i].second;auto xc_mp=dfs(x);for(auto [xc,cnt]:xc_mp){c_mp[xc]+=cnt;//把孩子的颜色列表更新到该点if(c_mp[mx]<c_mp[xc]||(c_mp[mx]==c_mp[xc]&&mx>xc)){//有颜色更多的 标号更小的 更新mx=xc;}}}//当前颜色c_mp[c[now]]++;if(c_mp[mx]<c_mp[c[now]]||(c_mp[mx]==c_mp[c[now]]&&mx>c[now]))mx=c[now];ans[now]=mx;return c_mp;
}
void solve(){int n;cin>>n;forr(i,1,n){cin>>c[i];}forr(i,1,n-1){int u,v;cin>>u>>v;e[u].emplace_back(0,v);deg[v]++;}int rt=0;forr(i,1,n)if(deg[i]==0){rt=i;break;}cal_sz(rt);dfs(rt);forr(i,1,n)cout<<ans[i]<<' '; 
}
http://www.dtcms.com/a/403994.html

相关文章:

  • 【系统架构设计(36)】网络规划与设计
  • SQL 注入风险与解决方案实战解析
  • 企业如何做网站推广出名的包装设计
  • 【STM32】位带操作
  • 供需网站开发做网站怎么发布
  • 保定网站建设方法水墨画风格网站
  • LINUX嵌入式面经(六)--常见算法篇
  • 网站优化推广方法庐江住房建设局网站
  • C语言基础【24】:组包和解包
  • 网站建设PHP开发是什么意思长沙seo服务
  • BMAD的多代理协同开发工作流指南
  • 沈阳网站建设 景乔科技毕节做网站
  • 网站开发 前端 后端 如何结合他达拉非片和西地那非片的区别
  • 做国际物流需要自己的网站吗win主机 wordpress静态
  • 指令微调数据评估与影响:构建高质量大语言模型的关键
  • 本墨陈黑做网站有版权网站开发维护成本
  • 【自动驾驶】自动驾驶概述 ⑤ ( 自动驾驶硬件概述 | 车载计算单元 IPC | 车辆线控系统 )
  • 静态IP的适用场景
  • 第1章 计算机系统概述
  • 印刷个性化网站建设的意义残疾人无障碍网站怎么做
  • Linux学习笔记(六)--Linux进程概念
  • C语言自学--数据在内存中的存储
  • 石家庄网站制作哪家好wordpress 优化数据库
  • 《基于Qt的车载系统项目》
  • 有哪些免费推广软件网站seo推广排名
  • 41.传输层协议UDP
  • 优良的定制网站建设提供商c2c模式的网站
  • 记力扣2516.每种字符至少取k个 练习理解
  • 广州站电话科创纵横 网站建设
  • 进程与集群:提升性能