1. 程式人生 > 其它 >AtCoder Beginner Contest 210 A~D 題解

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