AtCoder Beginner Contest 210 A~D 题解
题面
A
简单的数学应用题,分段函数
read(n);read(a);read(x);read(y);
ans=min(n,a)*x;
if (n>a) ans+=y*(n-a);
printf("%lld\n",ans);
B
第一个出现1的位置若是奇数,输出Takahashi,否则输出Aoki
read(n);
scanf("%s",a+1);
for (i=1;i<=n;i++) if (a[i]=='1')
{
if (i&1) cout<<"Takahashi";else cout<<"Aoki";return 0;
}
C
离散化,开个桶,从左往右扫
read(n);read(k);
for (i=1;i<=n;i++) read(c[i]),a[i]=c[i];
sort(a+1,a+n+1);
cnt=unique(a+1,a+n+1)-a-1;
for (i=1;i<=n;i++)
{
int co=lower_bound(a+1,a+cnt+1,c[i])-a;
if (s[co]==0) tot++;
s[co]++;
if (i>k)
{
int tmp=lower_bound(a+1,a+cnt+1,c[i-k])-a;
s[tmp]--;
if (s[tmp]==0) tot--;
}
if (i>=k) ans=max(ans,tot);
}
printf("%lld\n",ans);
D
我们考虑一个点和所有在它左上方点的距离最小值可以从它左边的点和上方的点转移而来,并且与在它和它左边的点,它和它上方的点建车站的值求min,于是我们处理了左上和右下的点(包括正上正下,正左正右)之间的值,同理右上和左下的点也可以用同样方法处理
read(n);read(m);read(c);
for (i=1;i<=n;i++) for (j=1;j<=m;j++) read(a[i][j]),f[i][j]=g[i][j]=(1ll<<62);
ans=(1ll<<62);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
{
if (i==1&&j==1) continue;
if (i!=1&&j!=1) f[i][j]=min(f[i-1][j]-a[i-1][j],f[i][j-1]-a[i][j-1])+c+a[i][j];
if (i!=1) f[i][j]=min(f[i][j],a[i-1][j]+a[i][j]+c);
if (j!=1) f[i][j]=min(f[i][j],a[i][j-1]+a[i][j]+c);
if (i==1) f[i][j]=min(f[i][j],f[i][j-1]-a[i][j-1]+a[i][j]+c);
if (j==1) f[i][j]=min(f[i][j],f[i-1][j]-a[i-1][j]+a[i][j]+c);
ans=min(ans,f[i][j]);
}
for (i=1;i<=n;i++)
for (j=m;j;j--)
{
if (i==1&&j==m) continue;
if (i!=1&&j!=m) g[i][j]=min(g[i-1][j]-a[i-1][j],g[i][j+1]-a[i][j+1])+c+a[i][j];
if (i!=1) g[i][j]=min(g[i][j],a[i-1][j]+a[i][j]+c);
if (j!=m) g[i][j]=min(g[i][j],a[i][j+1]+a[i][j]+c);
if (i==1) f[i][j]=min(f[i][j],f[i][j+1]-a[i][j+1]+a[i][j]+c);
if (j==m) f[i][j]=min(f[i][j],f[i-1][j]-a[i-1][j]+a[i][j]+c);
ans=min(ans,g[i][j]);
}
printf("%lld\n",ans);