首页 > 其他分享 >20241002测试

20241002测试

时间:2024-10-02 19:44:57浏览次数:1  
标签:20241002 int max sum mid times 测试 xrightarrow

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(n,s_0,s_1,k)\right)\) 考虑该式子,下面令 \(s_0'\),\(s_1'\),\(k'\) 表示能转移到 \(s_0\),\(s_1\),\(k\) 的状态。

\[\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 f(i-1,s_0',s_1',k')\\ +&\sum(\max(s_0,s_1)-\max(s_0',s_1'))\times 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;
}

标签:20241002,int,max,sum,mid,times,测试,xrightarrow
From: https://www.cnblogs.com/junjunccc/p/18445021

相关文章

  • 20241002
    bwtree我们可以设\(dp_{i,0/1}\)表示当前考虑至哪个点,这个节点的子树内选了几个叶子节点#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+5,INF=1e9;intn,a[N],dp[N][2];vector<int>g[N];voiddfs(intu,intf){dp[u][0]=(a[u]=......
  • LoongArch@微处理器体系结构专利技术研究方法@20241002
    微处理器体系结构专利技术研究方法第一辑:X86指令集总述 微处理器体系结构专利技术研究方法第二辑:x86多媒体指令集 微处理器体系结构专利技术研究方法第三辑:X86指令实现专利技术 ......
  • truffle部署合约ganache测试
     contract目录下 Storage.sol//SPDX-License-Identifier:GPL-3.0pragmasolidity>=0.8.2<0.9.0;/***@titleStorage*@devStore&retrievevalueinavariable*@custom:dev-run-script./scripts/deploy_with_ethers.ts*/contractSimpleSt......
  • React-测试驱动开发教程-全-
    React测试驱动开发教程(全)原文:Test-DrivenDevelopmentwithReact协议:CCBY-NC-SA4.0一、测试驱动开发的简短历史我写这一章的意图不是复制和粘贴博客中的陈词滥调(下面的摘录除外),或者假装我是历史事件的一部分(比如敏捷宣言或极限编程活动),这些事件导致了测试驱动开发......
  • 【防忘笔记】测试过程与技术
    测试人员应该想些什么我自己是做后端的,对于模棱两可的需求和莫名其妙的测试case是深恶痛绝的,所以有时候我就会想测试人员应该会需要注意什么?以他们的角度,他们更在乎什么最近有机会了解相关的知识,遂整理记录一下,以便之后在工作中更好的理解发生的各种事情以客户为中心这个真的......
  • 京东云金秋国庆上云服务器推荐(网站搭建,代码测试,企业官网,游戏联机服务器)
    轻量云主机是面向中小企业、开发者打造的预装精选软件、开箱即用的主机产品,快速搭建网站、电商、企业低代码工具箱,云盘、共享文档、知识库、开发测试环境等,相对普通云主机,按套餐购买更优惠、控制台可视化管理,运维更简单,提供更便捷上云体验。轻量云主机这个专区是本次活动的主......
  • 通义灵码加持的单元测试实践
    本文首先讲述了什么是单元测试、单元测试的价值、一个好的单元测试所具备的原则,进而引入如何去编写一个好的单元测试,通义灵码是如何快速生成单元测试的。什么是单元测试?单元测试是一种软件测试方法,通过编写代码来验证应用程序中最小的可测试单元(如单个函数、方法或类)的正确性......
  • pom web 自动化测试框架分享
    这是初版的pomweb测试框架,目录如下同时部分代码也放在下面,详细代码可前往github 查看,欢迎大家给出宝贵意见。|--base|base_page.py(封装方法)||--config|allure_config.py(测试报告配置)||--data|code(验证码)|user.yaml(用户目录)||--logs|log(日......
  • python tkinter 开发测试
    fromtkinterimport*defname_1_cs():ydm_1_2.place_forget()ydmwz_1_2.place_forget()ydmwz_1_2_B1.place_forget()xz_1_1.place_forget()ydmwz_1_2_B2.place_forget()xz_1_2.place_forget()mulu_1.place_forget()mulu_2.plac......
  • 云南省职业院校技能大赛赛项规程(软件测试)
    赛项名称:软件测试英文名称:SoftwareTesting赛项组别:高等职业教育赛项编号:GZ034目录一、赛项信息二、竞赛目标三、竞赛内容1、本赛项考查的技术技能和涵盖的职业典型工作任务2、专业核心能力与职业综合能力3、竞赛内容结构、成绩比例四、竞赛方式五、竞赛流程六、......