Codeforces Round #667 (Div. 3)

CF1409A Yet Another Two Integers Problem

洛谷传送门
CF1409A


分析

尽量填大的,那就是\(\lceil\frac{|a-b|}{10}\rceil\)


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans; 
}
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
signed main(){
	for (rr int T=iut();T;--T){
		rr int A=iut(),B=iut(),C;
		if (A<B) C=B-A; else C=A-B;
		print(C/10+((C%10)>0)),putchar(10);
	}
	return 0;
} 

CF1409B Minimum Product

洛谷传送门
CF1409B


分析

题目可以转换成找到一个\(k\),最小化
\((a-k)*(b-(n-k)),a-k\geq x,b-(n-k)\geq y\)
最小化的答案可以化简成
\(-k^2+(a+n-b)k+a(b-n)\)
\(\max\{y+n-b,0\}\leq k\leq \min\{a-x,n\}\)
由于它是个开口向下的二次函数,那么最小值应在左右边界之一


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef long long lll;
inline lll iut(){
	rr lll ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void print(lll ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
inline lll min(lll a,lll b){return a<b?a:b;}
inline lll max(lll a,lll b){return a>b?a:b;}
signed main(){
	for (rr int T=iut();T;--T){
		rr lll A=iut(),B=iut(),X=iut(),Y=iut(),
		n=min(iut(),A-X+B-Y),mn=max(n-B+Y,0),mx=min(A-X,n);
	    rr lll ans=A*(B-n)+min(mn*(A-B+n-mn),mx*(A-B+n-mx));
	    print(ans),putchar(10);
	}
	return 0;
}

CF1409C Yet Another Array Restoration

洛谷传送门
CF1409C


分析

题目也就是要找到尽量大的公差,
使得\(x,y\)在当中的前\(n\)项,
直接枚举即可


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
signed main(){
	for (rr int T=iut();T;--T){
		rr int n=iut(),A=iut(),B=iut();
		rr int ans=1e9,ans1,ans2;
		for (rr int st=1;st<=A;++st)
		for (rr int i=1;i<=B-A;++i)
		if (!((A-st)%i)&&!((B-st)%i)){
			if ((B-st)/i+1>n) continue;
			if (ans>st+i*(n-1)){
				ans=st+i*(n-1);
				ans1=st,ans2=i;
			}
		}
		for (rr int i=0;i<n;++i)
		    print(ans1+ans2*i),putchar(i==n-1?10:32);
	}
	return 0;
}

CF1409D Decrease the Sum of Digits

洛谷传送门
CF1409D


分析

显然把某一位加1再将后面的位置赋0或者原数才是最优的


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef long long lll;
inline lll iut(){
	rr lll ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void print(lll ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
inline lll dig(lll n){
	rr lll ans=0;
	for (;n;n/=10) ans+=n%10;
	return ans;
}
signed main(){
	for (rr int T=iut();T;--T,putchar(10)){
		rr lll n=iut(),s=iut(),now;
		if (dig(n)<=s) putchar(48);
		else{
			for (rr lll i=10;;i*=10)
			if (dig(now=(n/i+1)*i)<=s){
				print(now-n); break;
			}
		}
	}
}

CF1409E Two Platforms

洛谷传送门
CF1409E


分析

双指针处理前缀最大值和后缀最大值判断即可


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=200011;
int n,m,a[N],b[N],TOT,CNT[N],p[N],o[N],Pre[N],Suf[N],ans;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
signed main(){
	for (rr int T=iut();T;--T){
		n=iut(),m=iut(); ans=0; 
		for (rr int i=1;i<=n;++i) b[i]=a[i]=iut();
		for (rr int i=1;i<=n;++i) CNT[i]=0,iut();
		sort(b+1,b+1+n),TOT=unique(b+1,b+1+n)-b-1;
		for (rr int i=1;i<=n;++i) ++CNT[lower_bound(b+1,b+1+TOT,a[i])-b];
		for (rr int i=1;i<=TOT;++i) CNT[i]+=CNT[i-1];
		for (rr int i=1,j=1;i<=TOT;++i){
			for (;j<=i&&b[j]<b[i]-m;++j);
			o[i]=CNT[i]-CNT[j-1];
		}
		for (rr int i=TOT,j=TOT;i;--i){
			for (;j>=i&&b[j]>b[i]+m;--j);
			p[i]=CNT[j]-CNT[i-1];
		}
		Pre[0]=Suf[TOT+1]=0;
		for (rr int i=1;i<=TOT;++i) Pre[i]=max(Pre[i-1],o[i]);
		for (rr int i=TOT;i;--i) Suf[i]=max(Suf[i+1],p[i]);
		for (rr int i=1;i<=TOT;++i) ans=max(ans,Pre[i]+Suf[i+1]);
	    print(ans),putchar(10);
	}
	return 0;
} 

CF1409F Subsequences of Length Two

洛谷传送门
CF1409F


分析

\(dp[n][m][k]\)表示当前匹配的位置为\(n\)
\(t[0]\)相同的个数为\(m\),剩余次数为\(k\)的答案
也许记忆化搜索更为直观一点吧


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
int dp[211][211][211],n,m; char s[211];
inline signed max(int a,int b){return a>b?a:b;}
inline signed Dp(int dep,int now,int m){
	if (dep>n) return 0;
	if (~dp[dep][now][m]) return dp[dep][now][m];
	rr int ans=now*(s[dep]==s[n+2])+Dp(dep+1,now+(s[dep]==s[n+1]),m);
	if (m>0){
		ans=max(ans,Dp(dep+1,now+1,m-1));
		ans=max(ans,now+Dp(dep+1,now+(s[n+1]==s[n+2]),m-1));
	}
	return dp[dep][now][m]=ans;
}
signed main(){
	scanf("%d%d",&n,&m);
	memset(dp,-1,sizeof(dp));
	for (rr int i=1;i<=n+2;++i){
		rr char c=getchar();
		while (!islower(c)) c=getchar();
		s[i]=c;
	}
	return !printf("%d",Dp(1,0,m));
} 
posted @ 2020-11-01 19:54  lemondinosaur  阅读(87)  评论(0编辑  收藏  举报