Educational Codeforces Round 92 (Rated for Div. 2)

A. LCM Problem

题解

根据题意,\((l,2*l)\)必是最小解了

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
int T,n;
int main()
{
	T=read();
	while(T--)
	{
		n=read();
		if(n<=30)puts("NO");
		else
		{
			if(n==36)puts("YES\n5 6 10 15");
			else if(n==40)puts("YES\n6 10 15 9");
			else if(n==44)puts("YES\n6 7 10 21");
			else printf("YES\n%d %d %d %d\n",6,10,14,n-30); 
		}
	} 
	return 0;
}

B. Array Walk

题解

\(dp[i][j]\)表示当前在\(i\)位置,向左走了\(j\)次的最大收益,正常转移都是向左走再向右走回来,是算两步的,但是注意转移的时候还有一种情况,就是走到\(k-1\)步的时候直接来一个回首掏。

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
const int maxn=100010;
int T,n,K,z,a[maxn]; 
LL dp[maxn][7]; 
int main()
{
	T=read();
	while(T--)
	{
		n=read();K=read();z=read();
		for(int i=1;i<=n;i++)a[i]=read();
		for(int i=1;i<=n;i++)for(int j=0;j<=5;j++)dp[i][j]=0;
		dp[1][0]=a[1];
		LL ans=0;
		for(int i=2;i<=K+1;i++)
			for(int j=0;j<=z && i+2*j-1<=K;j++)
			{
				dp[i][j]=max(dp[i][j],dp[i-1][j]+a[i]);
				if(j)dp[i][j]=max(dp[i][j],dp[i][j-1]+a[i]+a[i-1]);
				if(i+2*j-1==K)ans=max(ans,dp[i][j]);
				if(j+1<=z && i+2*j-1==K-1)ans=max(ans,dp[i][j]+a[i-1]);
			}
		printf("%lld\n",ans); 
	}
	return 0;
}

C. Good String

题解

分奇偶讨论,若是奇就得全是一个数,偶的话就得两个数交替循环,10*10枚举那两个数是啥就行。

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
int T,len,cnt[20];
char s[200010];
int main()
{
	T=read(); 
	while(T--)
	{
		scanf("%s",s+1);
		for(int i=0;i<10;i++)cnt[i]=0;
		int len=strlen(s+1),ans,MAX=0;
		for(int i=1;i<=len;i++)cnt[s[i]-'0']++;
		for(int i=0;i<10;i++)MAX=max(MAX,cnt[i]);
		ans=len-MAX;
		for(int i=0;i<10;i++)
			for(int j=0;j<10;j++)
				if(i!=j)
				{
					int count=0,now=i;
					for(int k=1;k<=len;k++)
					{
						if(s[k]-'0'!=now)
						{
							count++;
						}
						else 
						{
							if(now==i)now=j;
							else now=i;
						}
					}
					if((len-count)%2)continue;
					ans=min(ans,count);
				}
		printf("%d\n",ans);
		
	}
	return 0;
}

D. Segment Intersections

题解

真的屑题,不想多说,分类讨论吧

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
const int maxn=200010;
int T;
PII a,b; 
LL k,n;
int main()
{
	T=read();
	while(T--)
	{
		n=read();k=read();
		a.X=read();a.Y=read();
		b.X=read();b.Y=read();
		if(a.Y>b.Y)swap(a,b);
		LL l1=a.X,l2=b.X,r1=a.Y,r2=b.Y;
		LL ans=0;
		if(l2>r1)
		{
			LL sum=r2-l1,pre=l2-r1;
			if(k<=sum)
			{
				printf("%lld\n",pre+k);
			}
			else
			{
				LL ans=pre+sum;
				k-=sum;
				bool ok=0;
				for(int i=2;i<=n;i++)
				{
					if(k<=sum)
					{
						ok=1;
						printf("%lld\n",ans+min(pre+k,2*k));
						break;
					} 
					else
					{
						if(2*k<pre+k)
						{
							ok=1;
							printf("%lld\n",ans+2*k);
							break;
						}	
						else ans+=pre+sum,k-=sum; 
					}
				}
				if(!ok)printf("%lld\n",ans+2*k); 
			}
		}
		if(l2<=r1)
		{
			LL pre=n*(r1-max(l2,l1));
			if(pre>=k)printf("0\n");
			else
			{
				k-=pre;
				LL len=n*(r2-min(l1,l2)-(r1-max(l1,l2	)));
				if(len>=k)printf("%lld\n",k);
				else printf("%lld\n",len+2*(k-len));
			}
		} 
	}
	return 0;
}

E. Calendar Ambiguity

题解

转化为公式

\[((y-1)*d+x)\%w=((x-1)*d+y)\%w \\ 移项(y-x)*(d-1)\equiv0\pmod {w} \]

先把\(d-1\)\(w\)的gcd给约掉,问题就变为了多少\((x,y)\)满足\(y-x\)是$ w'\(的倍数了。\)y-x$ 的取值范围为\([1,min(m,d)-1]\) ,设\(a=min(m,d)\) ,每次贡献的答案就是\(a-w',a-2*w',a-3*w'...\)\(k=\frac{min(m,d)-1}{w'}\) ,答案为\(k*a-(1+k)*k*w'/2\)

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
LL m,d,w;
int main()
{
	for(int T=read();T;T--)
	{
		m=read();d=read();w=read();
		w=w/__gcd(d-1,w);
		LL a=min(m,d),K=(a-1)/w;
		printf("%lld\n",K*a-(1+K)*K*w/2);
	}
	return 0;
}

废话

posted @ 2020-07-31 10:07  小飞淙的云端  阅读(23)  评论(0编辑  收藏