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;
}