20241002测试

news/2024/10/2 19:51:52

move

题面:
\(T\) 组数据,每组数据有 \(n\) 个数轴上的点 \(a_1,a_2,\dots,a_n\)。从原点开始,每次选择一个点未被选择过的点,如果当前在这个点上,那么分数加 \(1\),否则向这个点移动 \(1\) 格。问最高分数。
题解:
容易发现,要么先往左再往右,要么先往右再往左。先考虑第一种情况,枚举左端点,二分往右最远能到多远.
时间复杂度 \(\Theta(\sum n\log \sum n)\)
代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
template<typename T>inline void read(T&x){x=0;bool f=0;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')f=1;for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+(c^48);if(f)x=-x;
}
inline void Max(int&x,int y){x<y&&(x=y);
}
const int N=300005;
int T,n,a[N],b[N],cnta,cntb,cnt0,ans;
int main(){// freopen("move.in","r",stdin),freopen("move.out","w",stdout);for(read(T);T--;){read(n),cnta=cntb=cnt0=ans=0;for(int i=1,x;i<=n;i++){read(x);if(x<0)b[++cntb]=-x;if(x==0)cnt0++;if(x>0)a[++cnta]=x;}std::reverse(b+1,b+cntb+1);for(int i=0;i<=cntb;i++){if(cntb-i<b[i])break;int l=0,r=cnta,res=l;for(;l<=r;){int mid=(l+r)>>1;if(cnta-mid>=a[mid]+b[i])res=mid,l=mid+1;else r=mid-1;}Max(ans,i+res);}for(int i=0;i<=cnta;i++){if(cnta-i<a[i])break;int l=0,r=cntb,res=l;for(;l<=r;){int mid=(l+r)>>1;if(cntb-mid>=b[mid]+a[i])res=mid,l=mid+1;else r=mid-1;}Max(ans,i+res);}printf("%d\n",ans+cnt0);}return fflush(stdout),fclose(stdin),fclose(stdout),0;
}

string

题面:
\(T\) 组数据,每组数据两个字符串 \(A\)\(B\),已知 \(S\) 满足,\(A\)\(B\) 都是 \(S\) 的子串且出现相同次数,求 \(S\) 的最短长度,无解输出 \(-1\)
题解:
分成三种情况考虑:
如果说 \(A\)\(B\) 中出现了多次或者 \(B\)\(A\) 中出现了多次,那么无解。
如果 \(A\)\(B\) 中出现了一次,答案为 \(|B|\),如果 \(B\)\(A\) 中出现了一次,答案为 \(|A|\)
否则一定是将两个串的最长公共部分拼接起来。同时为 \(A\) 的前缀和 \(B\) 的后缀的最长串为 \(C_1\),反过来的为 \(C_2\),那么两个答案为 \(|A|+|B|-\max(|C_1|,|C_2|)\)
考虑使用 hash 实现,复杂度为 \(\text O(\sum|A|+ \sum|B|)\)
代码:

#include<cstdio>
#include<cstring>
typedef unsigned long long ull;
const int N=1000005;
ull base1=998244353,base2=1000000007,mod=1000000009;
int T,n,m;
char a[N],b[N],ab[N<<1],ba[N<<1];
struct Hash{ull h1,h2;bool operator==(Hash b){return h1==b.h1&&h2==b.h2;}
}hab[N<<1],hba[N<<1];
ull pow1[N<<1],pow2[N<<1];
inline Hash add(Hash x,char y){return{(x.h1*base1+(ull)y)%mod,(x.h2*base2+(ull)y)%mod};
}
inline Hash get(Hash*x,int l,int r){return{(x[r].h1+mod-x[l-1].h1*pow1[r-l+1]%mod)%mod,(x[r].h2+mod-x[l-1].h2*pow2[r-l+1]%mod)%mod};
}
inline int max(int x,int y){return x>y?x:y;
}
int main(){// freopen("string.in","r",stdin),freopen("string.out","w",stdout);for(scanf("%d",&T);T--;){scanf("%s%s",a+1,b+1),n=strlen(a+1),m=strlen(b+1);ab[n+1]=ba[m+1]='#',pow1[0]=pow2[0]=1;for(int i=1;i<=n;i++)ab[i]=a[i],ba[m+i+1]=a[i];for(int i=1;i<=m;i++)ab[n+i+1]=b[i],ba[i]=b[i];for(int i=1;i<=n+m+1;i++){pow1[i]=(pow1[i-1]*base1)%mod,pow2[i]=(pow2[i-1]*base2)%mod;hab[i]=add(hab[i-1],ab[i]),hba[i]=add(hba[i-1],ba[i]);}{int cntab=0,cntba=0;for(int i=n*2+1;i<=n+m+1;i++)if(hab[n]==get(hab,i-n+1,i))cntab++;for(int i=m*2+1;i<=n+m+1;i++)if(hba[m]==get(hba,i-m+1,i))cntba++;if(cntab>1||cntba>1){puts("-1");continue;}if(cntab==1){printf("%d\n",m);continue;}if(cntba==1){printf("%d\n",n);continue;}}int res1=0,res2=0;for(int i=1,j=n+m+1;i<=n&&j>n+1;i++,j--)if(hab[i]==get(hab,j,n+m+1))res1=i;for(int i=1,j=n+m+1;i<=m&&j>m+1;i++,j--)if(hba[i]==get(hba,j,n+m+1))res2=i;printf("%d\n",n+m-max(res1,res2));}return fflush(stdout),fclose(stdin),fclose(stdout);
}

game

题面:
\(n\) 轮石头剪刀布,对方第 \(i\) 轮的策略 \(b_i\) 可以是 \(\{-1,0,1,2\}\) 分别表示任意一种,石头,布,剪刀。现在要在连续两轮不能出相同手势的限制下求出最多的胜场,由于对方可以出 \(-1\),要求出所有情况下的答案的总和。
题解:
这题有点难度,不一定写的清楚。
考虑动态规划,定义状态 \(f(i,s_0,s_1,s_2)\) 表示和第 \(i\) 个对手出 \(0,1,2\) 的最大分数分别为 \(s_0,s_1,s_2\) 方案数。
若第 \(b_i\) 若能取到 \(0\)(即为 \(0\)\(-1\))则有:

\[f(i-1,s_0,s_1,s_2)\xrightarrow{\sum} f(i,\max(s_1,s_2),\max(s_0,s_2),-\infty) \]

\(b_i\) 能取到 \(1\)\(2\) 的方案同理。此时答案为 \(\sum\left(\max(s_0,s_1,s_2)\times f(n,s_0,s_1,s_2)\right)\)
目前复杂度 \(\text O(n^4)\),考虑优化。
发现一定有一维为 \(-\infty\)。定义状态 \(f(i,s_0,s_1,k)\) 表示 \(k\) 必输时,本轮平局或赢的得分分别为 \(s_0,s_1\) 的方案数。
此时答案转化为 \(\sum\left(\max(s_0,s_1)\times f(n,s_0,s_1,k)\right)\)
考虑转移,若 \(b_i\) 可以出 \(0\),那么有如下情况:
如果 \(b_{i-1}\) 可以是 \(0\) 那么有:

\[f(i-1,s_0,s_1,2)\xrightarrow{\sum} f(i,s_1,s_0+1,2) \]

如果 \(b_{i-1}\) 可以是 \(1\) 那么有:

\[f(i-1,s_0,s_1,0)\xrightarrow{\sum} f(i,\max(s_0+s_1),s_1+1,2) \]

如果 \(b_{i-1}\) 可以是 \(2\) 那么有:

\[f(i-1,s_0,s_1,1)\xrightarrow{\sum} f(i,s_0,\max(s_0,s_1)+1,2) \]

\(b_i\) 可以出 \(1\)\(2\) 的情况同理。
此时时间复杂度 \(\text O(n^3)\),可以继续优化。
由于答案式子为 \(\sum\left(\max(s_0,s_1)\times f(i,s_0,s_1,k)\right)\) 考虑该式子。

\[\begin{align*} \sum\left(\max(s_0,s_1)\times f(i,s_0,s_1,k)\right)= &\sum\max(s_0,s_1)\times\sum f(i-1,s_0',s_1',k')\\ =&\sum\max(s_0',s_1')\times\sum f(i-1,s_0',s_1',k')\\ +&\sum(\max(s_0,s_1)-\max(s_0',s_1'))\times\sum f(i-1,s_0',s_1',k')\\ \end{align*} \]

每次修改只用考虑后面部分的增量即可。
定义 \(\Delta(s_0',s_1')=\max(s_0,s_1)-\max(s_0',s_1')\) 那在如上 \(k=2\) 时的三种情况分别对应:
\(\Delta(s_0,s_1)=[s_0\ge s_1]\)\(\Delta(s_0,s_1)=[s_0\le s_1]\)\(\Delta(s_0,s_1)=1\)
修改状态定义 \(f(i,t,k)\) 表示 \(k\) 必输时,本轮平局或赢的得分 \(s_0,s_1\) 满足 \(s_0-s_1=t\) 的方案数。
可以得出状态转移方程并在转移的同时得到答案,下面继续考虑 \(k=2\) 的情况,下面 \(\Delta\)表示上面三种情况不同的\(\Delta(s_0,s_1)\)
如果 \(b_{i-1}\) 可以是 \(0\) 那么有:

\[f(i-1,t,2)\xrightarrow{\sum} f(i,-t+1,2),f(i-1,t,2)\times\Delta\xrightarrow{\sum}ans \]

如果 \(b_{i-1}\) 可以是 \(1\) 那么有:

\[f(i-1,t,0)\xrightarrow{\sum} f(i,\max(t,0)-1,2),f(i-1,t,0)\times\Delta\xrightarrow{\sum}ans \]

如果 \(b_{i-1}\) 可以是 \(2\) 那么有:

\[f(i-1,t,1)\xrightarrow{\sum} f(i,\min(t,0)-1,2),f(i-1,t,1)\times\Delta\xrightarrow{\sum}ans \]

\(b_i\) 可以出 \(1\)\(2\) 的情况同理。
此时的时间复杂度终于化为了 \(\Theta(n^2)\)

#include<cstdio>
#define int long long
template<typename T>inline void read(T&x){x=0;bool f=0;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')f=1;for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+(c^48);if(f)x=-x;
}
const int N=2005,mod=998244353;
int n,b[N],data[N][3][N<<1],*f[N][3],ans,get[3][3]={0,-1,1,1,0,-1,-1,1,0};
inline void Add(int&x,int y){(x+=y)>=mod&&(x-=mod);}
inline int mul(int x,int y){return x*y%mod;}
inline void Mul(int&x,int y){x=mul(x,y);}
inline int max(int x,int y){return x>y?x:y;}
inline int min(int x,int y){return x<y?x:y;}
inline int add(int x,int y){return Add(x,y),x;}
signed main(){// freopen("game.in","r",stdin),freopen("game.out","w",stdout);read(n);for(int i=1;i<=n;i++)read(b[i]);for(int i=1;i<=n;i++)for(int j=0;j<3;j++)f[i][j]=data[i][j]+N;if(~b[1])f[1][b[1]][1]=1,Add(ans,1);else for(int i=0;i<3;i++)f[1][i][1]=1,Add(ans,1);for(int i=2;i<=n;i++){if(b[i]==-1)Mul(ans,3);for(int lst=0;lst<3;lst++)for(int delta=-n;delta<=n;delta++)if(f[i-1][lst][delta]){int val=f[i-1][lst][delta];for(int nw=0;nw<3;nw++)if(b[i]==-1||b[i]==nw){int nwdelta;if(get[lst][nw]<0)Add(ans,val),nwdelta=max(delta,0)+1;else if(get[lst][nw]==0)Add(ans,(delta<=0)*val),nwdelta=-delta+1;else Add(ans,(delta>=0)*val),nwdelta=min(delta,0)+1;Add(f[i][nw][nwdelta],val);}}}printf("%lld\n",ans);return fflush(stdout),fclose(stdin),fclose(stdout),0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

git学习笔记 1

1、安装配置 git 安装:https://git-scm.com/book/zh/v2/起步-安装-Git 文档:https://git-scm.com/docs 初次配置git config --global user.name "你的名字"git config --global user.email "你的邮箱"检测配置是否成功 git config --list在里面找到 user…

高级语言程序设计课程第二次作业

班级链接:https://edu.cnblogs.com/campus/fzu 作业要求链接:https://edu.cnblogs.com/campus/fzu/2024C/homework/13282 学号:102400204 姓名:刘嘉奕 3.11编程作业 作业1目标:观察系统如何处理整数上溢,浮点数上溢,浮点数下溢作业2作业3双引号的打印需要使用转义序列作…

CF589H Tourist Guide

昨晚码敲完了没保存,导致还原卡直接把我码肘没了。。。 气死了只能重新敲了一遍。 题面 Tourist Guide 分析 考虑每一个联通块分开处理。 先将每一个联通块变为生成树,任意生成方式皆可。 对于每一个联通块,一定可以构造一种组合方法,使得该联通块中最多只有一个关键点无法…

2024新生赛-Week1

F12 快捷键f12直接查看字符串 xor 了解一下XOR运算,AB=C,CA=B 使用a数组对输入的字符进行循环运算取出最终的字符串再进行一次xor即可得到flag Ezencode进入加密函数后发现是一个base64算法,对表进行了替换,最后有对编码得到的结果进行异或操作. 提出最后的密文,进行异或,换表,…

DAY2-补题

我补题AK了,但你出言不逊是 非常好的一套题,让我的大脑旋转啊。 不太想开一个文章单独屑,所以扔到随笔里面。 敲字速度有待加强。 说在前面 题目难度单调递减,分数单调递减。果然屑死了。 T1再次读题失误,正确的来说是代码敲得非常抽象。T2DP但没骗到分非常不好,T3场上想…

独立站如何批量查收录,教你独立站如何批量查收录的方法操作步骤

独立站批量查收录是SEO优化工作中的重要环节,有助于网站管理员或SEO人员及时了解网站在搜索引擎中的表现,从而制定针对性的优化策略。以下是一些常用的独立站批量查收录的方法及其操作步骤: 一、使用搜索引擎的Site指令结合自动化脚本 编写脚本或配置爬虫: 利用Python、She…

04-论说文:审题与立意(1)

命题作文 比较开放 近义词 相关性 竞争 合作 竞争合作 ==》 竞争合作的关系 概率==》风险 风险 利益 审题 较难

南沙C++信奥赛陈老师解一本通题 1966:【14NOIP普及组】比例简化

​【题目描述】在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果。例如,对某一观点表示支持的有 1498 人,反对的有 902 人,那么赞同与反对的比例可以简单的记为1498:902。 不过,如果把调查结果就以这种方式呈现出来,大多数人肯定不会满意。因为这个比例…