zoukankan      html  css  js  c++  java
  • NOIP2020模拟赛(玖)题解

    今天莫名其妙就AK了貌似是水过去的,我还是蒟蒻是最弱的,%%%yzx

    A. 「NOIP模拟赛 玖」三个和尚

    三个和尚

    solve

    这道题刚开始没什么头绪,但通过观察发现,(f(x))相同的三个数相加都是3的倍数。我们可以证明

    我们发现(f(x)%3=x%3),因为x每次减去3的倍数%3都是不会变的

    所以((f(a)+f(b)+f(c))%3=f(a)%3+f(b)%3+f(c)%3=(a+b+c)%3=n%3))

    又因为(f(a)=f(b)=f(c))

    所以(n%3=0)

    我们就只需要判断(n%3)是否等于0

    由于这是一道构造题,只要输出答案n/3即可,套一下高精度就好了

    code

    #include<bits/stdc++.h>
    using namespace std;
    char s[100005];
    int a[100005],b[100005],len_a,len_b,sum,yu;
    int main(){
    	scanf("%s",s);len_a=strlen(s);
    	for(int i=0;i<len_a;i++)a[i]=s[i]-'0',sum+=a[i];
    	if(sum%3){printf("-1
    ");return 0;}
    	if(sum==0){printf("0 0 0
    ");return 0;}
    	for(int i=0;i<len_a;i++){
    		b[len_b++]=(yu+a[i])/3;
    		yu=(yu+a[i])%3;
    		yu*=10;
    	}
    	for(int i=1,j;i<=3;i++){
    		j=0;
    		while(b[j]==0)j++;
    		for(;j<len_b;j++)printf("%d",b[j]);
    		printf("%c",i<=2?' ':'
    ');
    	}
    	return 0;
    }
    

    B. 「NOIP模拟赛 玖」疯狂祖玛

    疯狂祖玛

    solve

    这道题拿到就是一道区间DP关键是怎么定义是问题,我们发现只定义二维(F[i][j])很难去写转移方程,由于n只有100我们可以再定义一维

    定义(F[i][j][k])表示i前面有k个和i颜色一样的球是,消除i-j这个区间上所有球需要花费的代价。

    想要消除只有两种方式

    ((i))在左右插球

    ((ii))从中间分开

    在这里要声明一下,在中间插球就是先分开再左右插球,右边插球和左边插球是相对的,所以只要往左边插球就好了。

    先考虑初始,因为不算(a[i])那个点,只要再打(K-k-1)个球就好了,(F[i][i][k]=K-k-1)

    求转移方程

    ((i))

    如果前面已经有K-1个球了也就是k=K-1就把a[i]直接消掉,然后把后面消掉(F[i][j][k]=min(F[i][j][k],f[i+1][j][0]))

    否则的话就塞呗(F[i][j][k]=min(F[i][j][i],F[i][j][k+1]+1))

    如果a[i]==a[i+1]的话,那就更新(F[i][j][k]=min(F[i][j][k],F[i+1][j][min(k+1,K-1)]))
    注意k+1可以超过值域,由于K个以上连续的和K个是等效的,所以要(min(k+1,min))

    ((ii))

    分开来的情况也好处理,我们用一个(p)扫过(i-j),如果发现(a[p+1]=a[i])那么我们就先把(i+1)(p)消掉,然后把(a[p+1])(a[i])接到一起消掉。于是转移方程(F[i][j][k]=min(F[i][j][k],F[i+1][p][0]+F[p+1][j][min(k+1,K-1)]))

    最后思考答案,非常简单(F[1][N][0])不做解释哈哈哈

    code

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=105;
    int N,K,F[maxn][maxn][maxn],a[maxn];
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    int main(){
    	N=read();K=read();
    	for(int i=1;i<=N;i++)a[i]=read();
    	memset(F,63,sizeof F);
    	for(int i=1;i<=N;i++)
    	for(int k=0;k<K;k++)F[i][i][k]=K-k-1;
    	for(int L=1;L<N;L++)
    	for(int i=1;i+L<=N;i++)
    	for(int k=K-1,j=i+L;k>=0;k--){
    		if(k==K-1)F[i][j][k]=min(F[i][j][k],F[i+1][j][0]);
    		else F[i][j][k]=min(F[i][j][k],F[i][j][k+1]+1);
    		if(a[i]==a[i+1])F[i][j][k]=min(F[i][j][k],F[i+1][j][min(k+1,K-1)]);
    		for(int p=i+1;p<j;p++)if(a[i]==a[p+1])F[i][j][k]=min(F[i][j][k],F[i+1][p][0]+F[p+1][j][min(k+1,K-1)]);
    	}
    	printf("%d
    ",F[1][N][0]);
    	return 0;
    }
    

    「NOIP模拟赛 玖」回文单词

    「NOIP模拟赛 玖」回文单词

    solve

    我们可以用两个指针向里面推,(hed)(til),有一个贪心的思想,就是有回文就马上用掉,lst_hed就是上一次的(hed),lst_til就是上一次的(til),只要发现lst_hedhed和tillst_til相等时,就视为回文串如何快速判断两个串是否相同呢,只要hash就好了,正向hash和反向hash的结果是一样的,原因相见秦九昭定义。

    原理上来说,写一个hash就足够了

    but!!!我写了4个!!!

    还记得ZS说过的哪个创奇,还记得wpy2018的4个hash

    在那一刻,我wpy附体!!!

    好吧还是一样的,时间还多,慎用啊!!!

    code

    //我4个哈希,要是挂了那就无语了,哎~ 
    #include<bits/stdc++.h>
    using namespace std;
    const int TT_1=9999991;
    const int TT_2=8710747;
    const int TT_3=9864191;
    const int TT_4=9525721;
    int N,len,ans,hed,til,lst_hed,lst_til,hash_h_1,hash_t_1,hash_1=37,F_1[1000005],hash_h_2,hash_t_2,hash_2=31,F_2[1000005],hash_h_3,hash_t_3,hash_3=41,F_3[1000005],hash_h_4,hash_t_4,hash_4=47,F_4[1000005];
    char s[1000005];
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    int main(){
    	N=read();
    	F_1[1]=1;for(int i=2;i<=1000000;i++)F_1[i]=F_1[i-1]*hash_1%TT_1;
    	F_2[1]=1;for(int i=2;i<=1000000;i++)F_2[i]=F_2[i-1]*hash_2%TT_2;
    	F_3[1]=1;for(int i=2;i<=1000000;i++)F_3[i]=F_3[i-1]*hash_3%TT_3;
    	F_4[1]=1;for(int i=2;i<=1000000;i++)F_4[i]=F_4[i-1]*hash_4%TT_4;
    	while(N--){
    		scanf("%s",s+1);
    		len=strlen(s+1);
    		hed=1;til=len;ans=0;lst_hed=0,lst_til=til+1;hash_h_1=hash_t_1=0;hash_h_2=hash_t_2=0;hash_h_3=hash_t_3=0;hash_h_4=hash_t_4=0;
    		while(hed<til){
    			hash_h_1=(hash_h_1*hash_1%TT_1+(s[hed]-'a'+1))%TT_1;
    			hash_h_2=(hash_h_2*hash_2%TT_2+(s[hed]-'a'+1))%TT_2;
    			hash_h_3=(hash_h_3*hash_3%TT_3+(s[hed]-'a'+1))%TT_3;
    			hash_h_4=(hash_h_4*hash_4%TT_4+(s[hed]-'a'+1))%TT_4;
    			hash_t_1=(hash_t_1+(s[til]-'a'+1)*F_1[lst_til-til]%TT_1)%TT_1;
    			hash_t_2=(hash_t_2+(s[til]-'a'+1)*F_2[lst_til-til]%TT_2)%TT_2;
    			hash_t_3=(hash_t_3+(s[til]-'a'+1)*F_3[lst_til-til]%TT_3)%TT_3;
    			hash_t_4=(hash_t_4+(s[til]-'a'+1)*F_4[lst_til-til]%TT_4)%TT_4;
    			if(hash_h_1==hash_t_1&&hash_h_2==hash_t_2&&hash_h_3==hash_t_3&&hash_h_4==hash_t_4){
    				ans+=2;lst_hed=hed;lst_til=til;hash_h_1=hash_t_1=0;hash_h_2=hash_t_2=0;hash_h_3=hash_t_3=0;hash_h_4=hash_t_4=0;
    			}
    			hed++;til--;
    		}
    		if(lst_hed!=lst_til-1)ans++;
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    over

  • 相关阅读:
    [原创]什么是兼容性测试?
    [原创]Web开发测试辅助工具介绍
    [原创]如何顺利通过中国电信Brew平台软件测试?
    [原创]网站性能优化利器之二"Yahoo Yslow"
    [原创]HP SiteScope工具介绍及下载地址
    [原创]网站前端页面级性能测试方法
    [原创]网银在线chinabank安全漏洞之“不完善的开发软件包”
    [原创] linux必学的常用命令
    [原创]如何做好目标管理?
    Visual Studio 小技巧:自定义代码片断
  • 原文地址:https://www.cnblogs.com/martian148/p/13326750.html
Copyright © 2011-2022 走看看