CF1102(*^▽^*)
A.Integer Sequence Dividing
题目大意:
给出
解题思路:
我们坚信它是可以分成我们想要的两个差值最小的集合的 差值一定和
详细一点:为了抵消差值,分集合时一定是
- 全部抵消完,差值一定为零。
- 剩下一个数,我们将
提出来,将剩下的 个数按照以上方式匹配,最开始的 即是差值。 - 剩下两个数,将
提出来,剩下的继续分,最后差值即为 也就是 。 - 剩下三个数,将
提出来,剩下的继续分,最后差值即为 也就是 。 - 剩下四个数?是不会剩下四个数的
综上,差值不是
真·小代码
#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
题目大意:
给出一个长度为
- 每种颜色必须用到
- 每个元素必须被染色
- 序列中相同的数字不能染上相同的颜色,即对于
,满足
若可行,则输出染色方案。
解题思路:
满足第一个要求,只需要从
不好的代码
#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
题目大意:
给定一个长度为
- 选择一个
,使得 - 选择一个
,使得 。
执行操作一的一方想要尽可能地使更多地
解题思路:
对
- 若
,由于没有操作次数的限制,所以最后序列中所有数一定会归零(感性理解为入不敷出迟早要没) - 若
,那么只有 才有可能被清零(感性理解为一次pass掉);又因操作二采取最优策略,每次一定会选择 进行操作,而操作完毕后 一定无法被一次清零;所以记 为原序列中 的个数,最后序列中会有 个数归零。
小代码
#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
题目大意:
给出一个长度为
解题思路:
显然贪心。若需要改动,一定要让
然后直接模拟就行了?
!代码很史,谨慎查看!
!代码很史,谨慎查看!
!代码很史,谨慎查看!
很史的代码
#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
题目大意:
给出一个长度为
- 对于
, 或 - 对于任意一组
,若满足 ,那么必须
要求输出构造
解题思路:
小清新计数题。
注意到条件三的限制,我们手模后发现对于满足
对于大区间
可结合图片食用
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
题目大意:
给定一个
确定矩形后,你可以通过以下顺序遍历整个矩阵:首先从顶部到底部遍历矩阵第一列,然后对第二列进行相同操作,以此类推。在遍历期间,按照遍历顺序记录序列
我们称一个
要求对于给出矩阵,合法的
解题思路:
看到数据范围,果断想到状压dp 但是我还是不会QwQ
注意到时限为4s。嗯4s。4s?4s!
设状态
其中
那么统计答案时,因为最后一行不确定,所以枚举最后一行的位置统计,即
其中
复杂度
不做评价的代码
#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;
}
完结撒花
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】