CF1102(*^▽^*)

news/2024/12/25 13:37:30/文章来源:https://www.cnblogs.com/Myyy-L/p/18556602

A.Integer Sequence Dividing

CF原题链接

题目大意:

给出\(n\),要求把序列\(1,2,…,n\)分成两个集合,输出两个集合的和的最小差值。\((1\leqslant n\leqslant 2\times 10^{9})\)

解题思路:

我们坚信它是可以分成我们想要的两个差值最小的集合的 差值一定和\(\Sigma_{i=1}^{n}i\)有关。若\(\Sigma_{i=1}^{n}i\)是偶数,那么差值为零,否则必为一。

详细一点:为了抵消差值,分集合时一定是\(1,n\)一组、\(2,n-1\)一组……以此类推。那么有以下几种情况:

  • 全部抵消完,差值一定为零。
  • 剩下一个数,我们将 \(1\) 提出来,将剩下的 \(n-1\) 个数按照以上方式匹配,最开始的 \(1\) 即是差值。
  • 剩下两个数,将 \(1,2\) 提出来,剩下的继续分,最后差值即为 \(2-1\) 也就是 \(1\)
  • 剩下三个数,将 \(1,2,3\) 提出来,剩下的继续分,最后差值即为 \(1+2-3\) 也就是 \(0\)
  • 剩下四个数?是不会剩下四个数的

综上,差值不是 \(0\) 就是 \(1\) 。那么显然,答案就和\(\Sigma ^{n}_{i=1}i\)的奇偶有关了。

真·小代码
#incIude <bits/stdc++.h>
#define int long long
using namespace std;
int n;signed main()
{scanf("%lld",&n);int sum=(n+1)*n/2;printf("%lld",sum%2);return 0;
}

B.Array K-Coloring

CF原题链接

题目大意:

给出一个长度为\(n\)的序列\(a\),用\(k\)种颜色染色,要求:

  • 每种颜色必须用到
  • 每个元素必须被染色
  • 序列中相同的数字不能染上相同的颜色,即对于\(a_{i}=a_{j},i\neq j\),满足\(col_{i}\neq col_{j}\)

若可行,则输出染色方案。\((1\leqslant k\leqslant n\leqslant 5000)\)

解题思路:

满足第一个要求,只需要从 \(1\)~\(k\) 反复给序列染色,每次++,超过\(k\)就归一;满足第三个要求,那么先给序列\(a\)排序,使相同的\(a_{i}\)在同一区间内被染色(根据染色方法,相邻两个元素不会染同样的色)。根据鸽巢原理,若元素\(a_{i}\)的数量超过\(k\),那么一定无法染色

不好的代码
#incIude <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5005;
int n,k;
struct node{int x,d,col;
}a[N];
int p;bool cmp1(node x,node y) {  return x.x<y.x;  }
bool cmp2(node x,node y) {  return x.d<y.d;  }
signed main()
{scanf("%lld%lld",&n,&k);for (int i=1;i<=n;i++) {scanf("%lld",&a[i].x);a[i].d=i;}sort(a+1,a+1+n,cmp1);p=1;//颜色指针int cnt=1;//记录相同元素的个数for (int i=1;i<=n;i++){if (a[i].x==a[i-1].x) cnt++;else cnt=1;if (cnt>k) { printf("NO"); return 0; }a[i].col=p++;if (p>k) p=1;}sort(a+1,a+1+n,cmp2);printf("YES\n");for (int i=1;i<=n;i++) printf("%lld ",a[i].col);return 0;
}

C.Doors Break and Repairing

CF原题链接

题目大意:

给定一个长度为\(n\)的数列\(a\),以下两个操作交替进行:

  1. 选择一个\(a_{i}\neq0\),使得\(a_{i}=max(a_{i}-x\ ,\ 0\ )\)
  2. 选择一个\(a_{i}\neq0\),使得\(a_{i}=a_{i}+y\)

执行操作一的一方想要尽可能地使更多地\(a_{i}\)变成 \(0\),执行操作二的一方想要尽可能地让更少的\(a_{i}\)变成 \(0\)。求双方都采取最优策略时,最多有多少个\(a_{i}\)\(0\)\((1\leqslant n\leqslant 100,1\leqslant x,y,a_{i}\leqslant 10^{5})\)

解题思路:

\(x,y\)的关系进行分类讨论。

  • \(x>y\),由于没有操作次数的限制,所以最后序列中所有数一定会归零(感性理解为入不敷出迟早要没)
  • \(x\leqslant y\),那么只有\(a_{i}\leqslant x\)才有可能被清零(感性理解为一次pass掉);又因操作二采取最优策略,每次一定会选择\(a_{i}\leqslant x\)进行操作,而操作完毕后\(a_{i}\)一定无法被一次清零;所以记\(cnt\)为原序列中\(a_{i}\leqslant x\)的个数,最后序列中会有\(\lceil \frac{cnt}{2}\rceil\)个数归零。
小代码
#incIude <bits/stdc++.h>
#define int long long
using namespace std;
const int N=110;
int n,x,y;
int a[N];
int cnt;signed main()
{scanf("%lld%lld%lld",&n,&x,&y);for (int i=1;i<=n;i++) {scanf("%lld",&a[i]);if (a[i]<=x) cnt++;}if (x>y) printf("%lld",n);else printf("%lld",(cnt+1)/2);return 0;
}

D.Balanced Ternary String

CF原题链接

题目大意:

给出一个长度为\(n\)、仅由'\(0\)','\(1\)','\(2\)'组成的字符串\(s\),要求改动最少的位置,使得\(s\)\(0,1,2\)的个数相同;若有多种方案,输出字典序最小的一个。\((\)保证\(n\)\(3\)的倍数,\(3\leqslant n\leqslant 3\times 10^{5})\)

解题思路:

显然贪心。若需要改动,一定要让\(0\)尽量靠前,\(2\)尽量靠后,\(1\)最后考虑。

然后直接模拟就行了?

!代码很史,谨慎查看!
!代码很史,谨慎查看!
!代码很史,谨慎查看!

很史的代码
#incIude <bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
int n;
char s[N];
int num;
int bx[3];//每个字符出现的个数 
vector <int> d[3];
int l[3],r[3];//指针,指向改动的最前、最后位置signed main()
{scanf("%lld%s",&n,s);num=n/3;for (int i=0;i<n;i++) {bx[(int)(s[i]-'0')]++;d[(int)(s[i]-'0')].push_back(i);}r[0]=bx[0]-1,r[1]=bx[1]-1,r[2]=bx[2]-1;while (bx[0]<num){int mn=inf;//0尽量靠前if (bx[1]>num) mn=min(mn,d[1][l[1]]);if (bx[2]>num) mn=min(mn,d[2][l[2]]);bx[0]++;s[mn]='0';if (bx[1]>num&&mn==d[1][l[1]]) l[1]++,bx[1]--;else l[2]++,bx[2]--;}while (bx[2]<num){int mx=0;//2尽量靠后if (bx[1]>num) mx=max(mx,d[1][r[1]]);if (bx[0]>num) mx=max(mx,d[0][r[0]]);bx[2]++;s[mx]='2';if (bx[1]>num&&mx==d[1][r[1]]) r[1]--,bx[1]--;else r[0]--,bx[0]--;}while (bx[1]<num){int dd;if (bx[0]>num) dd=d[0][r[0]];//1最后看情况else dd=d[2][l[2]];bx[1]++;s[dd]='1';if (bx[0]>num) r[0]--,bx[0]--;else l[2]++,bx[2]--;}printf("%s",s);return 0;
//都看到这了,为蒟蒻的代码提提建议吧,总感觉这样写太废太冗杂了……
}

E.Monotonic Renumeration

CF原题链接

题目大意:

给出一个长度为\(n\)的序列\(a\),需构造一个单调不降的序列\(b\),满足:

  1. \(b_{1}=0\)
  2. 对于\(i\in [2,n]\)\(b_{i}=b_{i-1}\)\(b_{i}=b_{i-1}+1\)
  3. 对于任意一组\(i,j\),若满足\(a_{i}=a_{j}\),那么必须\(b_{i}=b_{j}\)

要求输出构造\(b\)序列的方案数,对\(998244353\)取模\((2\leqslant n\leqslant 2\times10^{5},1\leqslant a_{i}\leqslant 10^{9})\)

解题思路:

小清新计数题。

注意到条件三的限制,我们手模后发现对于满足\(a_{i}=a_{j}\)的区间\([i,j]\),应也满足\(b_{i}=b_{i+1}=…=b_{j}\),不然无法保证\(b\)序列单调不降。序列\(a\)中会形成若干个以上描述的区间,若几个区间内有交,那么可以看作一个大区间(虽然大区间的两个端点\(i,j\)可能不满足\(a_{i}=a_{j}\),但仍需满足大区间内\(b\)中元素相等)。

对于大区间\([i,j]\),必然满足\(b_{i}=b_{i+1}=…=b_{j}\)。对于每个大区间\(i\),它有两种取值;于是统计大区间的个数\(cnt\),方案数就是\(2^{cnt-1}\)。(因为第一个区间,也就是\(b_{1}\)所在的区间取值是确定的)

可结合图片食用

um有点难评……那么,结合代码食用

可爱的小代码
#incIude <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
const int MOD=998244353;
int n;
int a[N];
map <int,int> mx,mn;//可恶的数据范围 不能用数组存
int tol;
struct node{int l,r;//记录对于相同元素a[i]所形成的最大区间
}st[N];bool cmp(node x,node y) {  return x.l<y.l;  }
int qsm(int a,int b)//注意到数据范围,选择快速幂
{int res=1;while (b){if (b&1) res=(res*a)%MOD;a=(a*a)%MOD;b>>=1;}return res;
}
signed main()
{scanf("%lld",&n);for (int i=1;i<=n;i++) scanf("%lld",&a[i]);for (int i=1;i<=n;i++) mx[a[i]]=i;//统计每个数出现的最初、最后位置for (int i=n;i>=1;i--) mn[a[i]]=i;for (int i=1;i<=n;i++) st[i]={mn[a[i]],mx[a[i]]};//记录a[i]所在的第一种区间sort(st+1,st+1+n,cmp);int r=st[1].r;for (int i=2;i<=n;i++)//统计不交区间个数{if (st[i].l>r) tol++;r=max(r,st[i].r);}printf("%lld",qsm(2,tol));return 0;
} 

F.Elongated Matrix

CF原题链接

题目大意:

给定一个\(n\)\(m\)列的矩阵\(a_{i,j}\),你可以改变每一行的顺序,但不能改变行内元素的位置。

确定矩形后,你可以通过以下顺序遍历整个矩阵:首先从顶部到底部遍历矩阵第一列,然后对第二列进行相同操作,以此类推。在遍历期间,按照遍历顺序记录序列\(s\),记为\(s_{1},s_{2},s_{3},…,s_{nm}\)

我们称一个\(k\)是合法的,当且仅当对于\(\forall i\in [2,nm]\),满足\(|s_{i}-s_{i-1}|\geqslant k\)

要求对于给出矩阵,合法的\(k\)值最大。\((1\leqslant n\leqslant 16,1\leqslant m\leqslant 10^{4},2\leqslant nm)\)

解题思路:

看到数据范围,果断想到状压dp 但是我还是不会QwQ

注意到时限为4s。嗯4s。4s?4s!

设状态\(f_{i,j}\)表示已选了\(i\)集合的行、以\(j\)行结尾的最大\(k\)值。状态转移方程即

\[f_{S\ \cup\ j,\ j}=max\{min\{f_{S,i},g_{i,j}\}\} \]

其中\(g_{i,j}\)表示第\(i,j\)行相邻时的最小差值,暂时不考虑第一行与最后一行的差值

那么统计答案时,因为最后一行不确定,所以枚举最后一行的位置统计,即

\[Ans=max\{min\{f_{(1<<n)-1,i},h_{k,i}\}\} \]

其中\(h_{k,i}\)表示第\(k\)行作为第一行、第\(i\)行作为最后一行时两行的最小差值。

复杂度\(O(2^{n}n^{3})\)

不做评价的代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=20;
const int M=1e4+5;
const int inf=0x3f3f3f3f3f3f3f3f;
int n,m;
int a[N][M];
int f[1<<N][N],g[N][N],h[N][N];
int ans;signed main()
{scanf("%lld%lld",&n,&m);for (int i=0;i<n;i++){for (int j=1;j<=m;j++) scanf("%lld",&a[i][j]);}//预处理 for (int i=0;i<n;i++)//i,j分别枚举行 {for (int j=0;j<n;j++){g[i][j]=h[i][j]=inf;for (int k=1;k<=m;k++) g[i][j]=min(g[i][j],abs(a[i][k]-a[j][k]));//枚举第二维坐标 for (int k=2;k<=m;k++) h[i][j]=min(h[i][j],abs(a[i][k-1]-a[j][k]));}}for (int k=0;k<n;k++)//枚举第一行 {memset(f,0,sizeof f);f[1<<k][k]=inf;for (int s=0;s<(1<<n);s++)//枚举行的集合 {for (int i=0;i<n;i++) {if (!(s&(1<<i))) continue;for (int j=0;j<n;j++){if (!(s&(1<<j))) f[s|(1<<j)][j]=max(f[s|(1<<j)][j],min(f[s][i],g[i][j]));}}}for (int i=0;i<n;i++) ans=max(ans,min(f[(1<<n)-1][i],h[k][i]));//枚举最后一行并统计答案 }printf("%lld",ans);return 0;
}

完结撒花

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

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

相关文章

Qt - 多线程之线程的开始、暂停、恢复、停止

示例1 在Qt中,可以使用QThread的线程控制功能来暂停和恢复一个线程。这里是一个简单的例子:#include <QThread> #include <QDebug>class WorkerThread : public QThread {void run() override {qDebug() << "Thread is running";// 执行一些任务…

linux学习day03_linux文件与目录管理

1、相对路径和绝对路径的区别 绝对路径:路径的写法“一定由根目录 / 写起”,例如: /usr/share/doc 这个目录。相对路径:路径的写法“不是由 / 写起”,例如由 /usr/share/doc 要到 /usr/share/man 下面 时,可以写成: “cd ../man”这就是相对路径的写法啦!相对路径意指“…

我为什么要舍弃CSDN改用博客园

作为博客园老用户,我希望更加积极的在博客园分享技术而非CSDN,因为CSDN没有开放性,什么都要审核着实很烦! 下面是我在CSDN十余年耕耘,仅收获了一堆无用的破勋章和一万多粉丝,因为不怎么回消息答疑铁粉很少。下面是我跟CSDN在线客服的对话: 下面是客服回复给我的原文:抱…

Qt - 多线程之线程同步

一、线程为什么要同步 使用两个线程对一个全局变量做累加,从0加到10,所以只要每个线程累加到5就行。代码如下所示: #include <QApplication> #include <QThread> #include <QDebug>// 定义共享资源 int sharedValue = 0;// 定义一个线程类 class MyThread…

el-input 输入框加%号后缀

<el-input><i slot="suffix">%</i> </el-input> 如图学如逆水行舟,不进则退

人工智能之机器学习线代基础——克拉默法则(Cramers Rule)

克拉默法则是一种用于解 线性方程组 的方法,适用于系数矩阵为 方阵 的情况(即未知数的个数与方程的个数相等)。它通过计算行列式直接求解方程组的解。 克拉默法则的优缺点 优点直接性:可以显式地通过行列式计算出解。 理论价值:适合小规模问题,易于理解和验证解的正确性…

CommonsBeanUtils1(基于ysoserial)

环境准备 JDK1.8(8u421) JDK8的版本应该都没什么影响,这里直接以我的镜像为准了、commons-beanutils:commons-beanutils:1.9.2、commons-collections:commons-collections:3.2、javassist:javassist:3.12.0.GA mvn中加入以下依赖: <dependency><groupId>commons-…

【Mastercam 2025下载与安装教程 含补丁】

mastercam 2025是一款专门用于数控加工的软件,广泛应用于航空、汽车、机械制造等领域可以帮助工程师、机械加工师等专业人员高效地进行零件的建模和加工,提高生产效益和质量。 系统要求‌操作系统‌:Windows 7或更高版本,64位操作系统。 ‌处理器‌:CPU频率至少为2GHz。 ‌内…

《刚刚问世》系列初窥篇-Java+Playwright自动化测试-5-创建首个自动化脚本(详细教程)

1.简介 前面几篇宏哥介绍了两种(java和maven)环境搭建和浏览器的启动方法,这篇文章宏哥将要介绍第一个自动化测试脚本。前边环境都搭建成功了,浏览器也驱动成功了,那么我们不着急学习其他内容,首先宏哥搭建好的环境中创建首个完整的自动化测试脚本,让小伙伴或者童鞋们提…

2024年腾讯云双十一薅羊毛最强攻略:错过一次又得等一年!

2024年腾讯云双十一活动为用户提供了丰富的云产品和优惠福利,以下是一份省钱、省心、省力的购买攻略,帮助大家制定必抢清单: 一、活动时间与入口活动时间:即日起至2024年11月30日23:59:59,具体以页面变更为准。 活动入口:腾讯云双十一活动页面二、优惠活动概览 1.服务器限…

BGP路由控制

BGP路由控制概述 BGP协议的重点不在于发现和计算路由,而在于通过丰富的属性和策略实现对路由的控制。 控制BGP路由可以通过两种方式实现。 一是通过BGP 的基本属性实现对BGP 选路的控制。这种方式比较简单,主要是通过配置、修改BGP 基本属性值以影响协议的选路,从而实现控制…

Windows右键新建列表排序

前言全局说明Windows右键新建列表排序一、说明 环境: Windows 11 家庭版 23H2 22631.3737二、Windows11 右键新建列表排序 2.1 打开注册表项 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\ShellNew2.2 编辑 Classes 键 调整成…