• Codeforces Round #493 (Div 2) (A~E)



    Codeforces 998

    比赛链接

    A.Balloons

    输出啥看错WA(*2)+第一次写sort写了cmp()但是没加cmpWA(*2)(结构体重载运算符后遗症)。。
    没谁了。

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    const int N=150;
    
    int n,A[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    
    int main()
    {
    	n=read(); int pos=1,sum=0;
    	for(int i=1; i<=n; ++i)
    		sum+=(A[i]=read()), A[pos]>A[i]&&(pos=i);
    	sum-=A[pos];
    	if(sum<=A[pos]) puts("-1");
    	else
    	{
    		printf("%d
    ",n-1);
    		for(int i=1; i<=n; ++i) if(i!=pos) printf("%d ",i);
    	}
    
    	return 0;
    }
    

    B.Cutting

    能切割的位置显然确定。

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    const int N=1004;
    
    int n,B,A[N],c[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    
    int main()
    {
    	n=read(),B=read();
    	int cnt=0;
    	for(int i=1; i<=n; ++i) A[i]=read();
    	for(int i=1,odd=0,even=0; i<=n; ++i)
    	{
    		if(A[i]&1) ++odd; else ++even;
    		if(odd==even&&i!=n) c[++cnt]=std::abs(A[i+1]-A[i]);
    	}
    	std::sort(c+1,c+1+cnt);
    	int res=0;
    	for(int i=1; i<=cnt; ++i)
    		if(B>=c[i]) ++res, B-=c[i];
    		else break;
    	printf("%d",res);
    
    	return 0;
    }
    

    C.Convert to Ones

    如果X,Y的大小关系确定,那可以完全利用小的那个。即策略只有两种:把所有0换在一起,一次反转;反转所有段的0。统计有多少段0即可。
    当时闲的数了一下1的段数,然后就把zero和one写反了,然后就被MainTest给×了==。

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    using std::min;
    typedef long long LL;
    const int N=4e5+7;
    const LL INF=1e17;
    
    int n;
    LL X,Y;
    char s[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    
    int main()
    {
    	n=read(), X=read(), Y=read(), scanf("%s",s+1);
    	int cnt=0;
    	for(int i=1; i<=n; ++i) if(s[i]=='0') ++cnt;
    	if(!cnt) return putchar('0'),0;//判1的话还要判一下这个...
    	if(cnt==n) return printf("%I64d",Y),0;
    
    	LL zero=0,one=0;
    	if(s[1]=='0') ++zero; else ++one;
    	for(int i=2; i<=n; ++i)
    		if(s[i]=='1'&&s[i-1]=='0') ++one;
    		else if(s[i]=='0'&&s[i-1]=='1') ++zero;
    	printf("%I64d",min((zero-1ll)*X+Y,min(zero*Y,min((one-1ll)*X+2ll*Y,one*Y+Y))));
    
    	return 0;
    }
    

    比赛结束后

    D.Roman Digits

    由于序列长度n是固定的,我们可以假设最初有n个1,然后用5,10,50去替换,即求从{0,4,9,49}中选n个数能组成多少个不同的。
    先看{0,4,9}。问题在于一个数可以有多种表示。在使用4的个数大于9之后,一部分4是可以用9替换的,多余的位置用0补。
    所以如果暴力的话,4的个数只需从0枚举到min(n,8),然后选一些9,这样每次都能组成一个不同的数。
    对于{0,4,9,49},可以用类似方法暴力计算(9只需要枚举到min(n,48)吗...并不清楚)。
    打表后可以发现,n>=12时,n每加一,组成数的个数+49,即都能组成。然后只需要算n<=12的就OK了。
    嗯。。不会证。

    还有种思路(Way2):
    我们考虑一下有多种表示的数字的可能。可以先通过打表找到有多种表示的数字,能发现从45往后都可以。(然而好像并没什么用)

    [9*5 = 4*10 + 5*1\ 9*10 = 1*50 + 8*5\ 5*10 + 1*5 = 1*50 + 5*1]

    这意味着我们不需要 超过8个的5、超过8个的10、超过4个的10且至少1个5。那枚举时范围就很小了。
    后面没看明白 不写了。。

    还有一种思路:

    找到个证明(然而没啥用 也不想看 先粘这了):

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    const int N=1e4+5;
    const int Ans[17]={0,4,10,20,35,56,83,116,155,198,244,292,341,390};
    
    namespace Way2
    {
    	bool use[200];
    	int Judge(int n)
    	{
    		memset(use,0,sizeof use);
    		for(int i=0; i<=20; ++i)
    			for(int j=0; j<=20; ++j)
    				for(int k=0; k<=20; ++k)
    					for(int l=0; l<=20; ++l)
    						if(i+j*5+k*10+l*50==n && use[i+j+k+l]) return 1;
    						else if(i+j*5+k*10+l*50==n) use[i+j+k+l]=1;// printf("%d=%d+%d*5+%d*10+%d*50
    ",n,i,j,k,l);
    		return 0;
    	}
    	void Main()
    	{
    		for(int i=1; i<=100; ++i)
    			if(Judge(i)) printf("%d
    ",i);	
    	}
    }
    
    long long Calc(int n)
    {
    	return Ans[n];
    	static bool vis[N];
    	memset(vis,0,sizeof vis);
    	long long ans=0;
    	for(int i=0; i<=8; ++i)
    		for(int j=0; j<=8; ++j)
    			for(int k=0; k<=48; ++k)//我也不知道最小可以枚举到多少...大点吧 
    				if(i+j+k<=n && !vis[i*4+j*9+k*49])
    					vis[i*4+j*9+k*49]=1, ++ans;
    	return printf("%d:",n),ans;
    }
    
    int main()
    {
    	int n; scanf("%d",&n);
    	if(n<=12) printf("%I64d
    ",Calc(n));
    	else printf("%I64d
    ",Calc(12)+1ll*(n-12)*49);
    
    	return 0;
    }
    

    E.Sky Full of Stars(容斥 计数)

    单独写一篇,见这儿

    //1107ms	7700KB
    #include <cstdio>
    #include <algorithm>
    #define mod (998244353)
    typedef long long LL;
    const int N=1e6+7;
    
    int C[N],inv[N];
    
    inline LL FP(LL x,int k)
    {
    	LL t=1;
    	for(; k; k>>=1,x=x*x%mod)
    		if(k&1) t=t*x%mod;
    	return t;
    }
    
    int main()
    {
    	int n; scanf("%d",&n);
    	LL ans1=0; C[0]=inv[1]=1;
    	for(int i=1; i<=n; ++i)
    	{
    		if(i>1) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    		C[i]=1ll*(n-i+1)*C[i-1]%mod*inv[i]%mod;
    		if(i&1) ans1+=1ll*C[i]*FP(3,(1ll*n*(n-i)+i)%(mod-1))%mod;//a^{varphi(p)}=1(mod p)
    		else ans1-=1ll*C[i]*FP(3,(1ll*n*(n-i)+i)%(mod-1))%mod;
    	}
    	ans1=2ll*ans1%mod;
    	LL ans2=0;
    	for(int i=0,pw3=1; i<n; ++i)
    	{
    		if(i&1) ans2+=1ll*C[i]*(FP(1+mod-pw3,n)-FP(mod-pw3,n))%mod;
    		else ans2-=1ll*C[i]*(FP(1+mod-pw3,n)-FP(mod-pw3,n))%mod;
    		pw3=3ll*pw3%mod;
    	}
    	printf("%I64d
    ",((ans1+3ll*ans2)%mod+mod)%mod);
    
    	return 0;
    }
    
  • 相关阅读:
    【K8s】二进制部署Kubernetes v1.8.15集群环境管理Docker容器
    swift开发笔记10
    解读苹果app证书和描述文件
    swift开发笔记09
    swift开发笔记07
    swift开发笔记08
    默认显示detailViewController
    金融理财类app,被苹果审核拒绝
    swift开发笔记05
    Git安装图解
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9287988.html
Copyright © 2020-2023  润新知