Codeforces Round #667 (Div. 3)
比赛链接:https://codeforces.com/contest/1409
A. Yet Another Two Integers Problem
题解
按照贪心的思路,肯定先取 10 10 10,到最后差值小于 10 10 10再取这个差值即可。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e5+7;
int a[N];
void solve(){
int a=read(),b=read();
if(b>a) cout<<(b-a+9)/10<<endl;
else cout<<(a-b+9)/10<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=read();
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
B. Minimum Product
题解
考虑先减 a a a再减 b b b和先减 b b b再减 a a a的乘积的最小值即可
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e5+7;
int a[N];
void solve(){
int a=read(),b=read(),x=read(),y=read(),n=read();
int num1=min(a-x,n);
int num2=min(b-y,n);
// outval2(num1,num2);
if(a-num1<b-num2){
cout<<1ll*(a-num1)*(max(y,b-(n-num1)))<<endl;
}
else {
cout<<1ll*(b-num2)*(max(x,a-(n-num2)))<<endl;
}
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=read();
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
C. Yet Another Array Restoration
题解
题目给的范围很小,可以直接暴力枚举差值 d e l t a delta delta,然后贪心地先从 y y y开始取,每次减 d e l t a delta delta直到小于 1 1 1,当小于 y y y的个数小于 n n n时,可以从 y y y开始每次加 d e l t a delta delta,时间复杂度为 O ( n 2 ) O(n^{2}) O(n2)。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e5+7;
int a[N];
void solve(){
int n=read(),x=read(),y=read();
int len=y;
rp(delta,1,len){
set<int> s;
int cur=y;
while(cur>0&&s.size()<n){
s.insert(cur),cur-=delta;
}
if(s.find(x)!=s.end()){
int cur=y+delta;
while(s.size()<n) s.insert(cur),cur+=delta;
int f=1;
for(auto val:s){
if(f) cout<<val,f=0;
else cout<<" "<<val;
}
cout<<endl;
return ;
}
}
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=read();
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
D. Decrease the Sum of Digits
题解
根据贪心的原则,我们需要逆序从个位数开始枚举到最大位数,如果当前位 + + +前面的数位和比 k k k大,我们就需要把当前位置为 0 0 0,即加上 ( 10 − c u r ) (10-cur) (10−cur)% 10 10 10,然后把这个数的影响加上,我们用一个数组维护这个要加的数即可。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 1e5+7;
int sum[100];
int a[100],tot;
void solve(){
ll n;scl(n);int s=read();
tot=0;a[0]=0;
while(n>0) a[++tot]=n%10,n/=10;
rp(i,1,tot/2) swap(a[i],a[tot-i+1]);
vector<int> ans;
int sum=0;
rp(i,1,tot) sum+=a[i];
RP(i,tot,1){
if(sum<=s) break;
if(!a[i]){
ans.push_back(0);
continue;
}
else ans.push_back(10-a[i]);
a[i-1]++;
RP(j,i-1,0){
if(a[j]==10) a[j]=0,a[j-1]++;
}
sum=0;
rp(j,0,i-1) sum+=a[j];
// outval2(i,sum);
}
if(ans.size()==0){
cout<<0<<endl;
return ;
}
reverse(ans.begin(),ans.end());
for(auto val:ans) cout<<val;
cout<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=read();
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
E. Two Platforms
题解
其实就是让你求出两个相等区间能够覆盖的最大点数。
第一想法是先取最大的,然后取次大的,但是这样会有可能导致和不是最大的(伪贪心)。
h
a
c
k
hack
hack数据:
假设
n
n
n为
8
8
8,
K
K
K为
4
4
4。
这
n
n
n个点的
x
x
x坐标分别为:
2
2
2
3
3
3
5
5
5
6
6
6
7
7
7
8
8
8
9
9
9
11
11
11
那么基于上述贪心的做法是先选
[
5
,
6
,
7
,
8
,
9
]
[5,6,7,8,9]
[5,6,7,8,9],再选
[
2
,
3
]
[2,3]
[2,3],答案为
5
+
2
=
7
5+2=7
5+2=7。
而最优解是先选
[
2
,
3
,
5
,
6
]
[2,3,5,6]
[2,3,5,6],再选
[
7
,
8
,
9
,
11
]
[7,8,9,11]
[7,8,9,11],答案为
4
+
4
=
8
4+4=8
4+4=8。
因此我们需要考虑有没有一种能找到所有情况的做法。
我们可以先枚举一个区间,然后维护在这个区间后面所有的区间中覆盖的最多点数(可以逆序预处理维护出来),最后在枚举过程中维护点数和的最大值即可。
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 2e5+7;
struct node{
int x,y;
bool operator < (node &others) const{
return x<others.x;
}
}p[N];
int MAX[N];
void solve(){
int n=read(),k=read();
rp(i,1,n) p[i].x=read();
rp(i,1,n) p[i].y=read();
sort(p+1,p+1+n);
vector<pii> vv;
rp(i,1,n){
int x=p[i].x;
int id=upper_bound(p+i+1,p+1+n,node{x+k,0})-p;
if(id>n) id=n;
else id--;
vv.push_back(m_p(i,id));
}
// for(auto val:vv) cout<<val.first<<" "<<val.second<<endl;
int res=0;
MAX[n]=0;
RP(i,n-1,0) MAX[i]=max(MAX[i+1],vv[i].second-vv[i].first+1);
// rp(i,0,n-1) cout<<MAX[i]<<" ";
// cout<<endl;
rp(i,0,n-1){
int len=vv[i].second-vv[i].first+1;
res=max(res,len+MAX[vv[i].second]);
// outval3(i,len,vv[i].second);
}
cout<<res<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=read();
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}
F. Subsequences of Length Two
题解
比较常见的
d
p
dp
dp,前两维状态不难想到,即
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示前
i
i
i个字符中,进行
j
j
j次修改的答案数。
但是考虑每次修改都会影响
t
0
t_{0}
t0的个数,因此我们需要再增加一维
k
k
k表示
t
0
t_{0}
t0的个数为
k
k
k的答案数。
状态:
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k]表示前
i
i
i个字符中,进行
j
j
j次修改,
t
0
t_{0}
t0的个数为
k
k
k的答案数。
边界条件:初始化为
−
1
-1
−1,
d
p
[
0
]
[
0
]
[
0
]
=
0
dp[0][0][0]=0
dp[0][0][0]=0;
状态转移方程:
考虑修改和不修改的情况。
1.不修改:
所有情况:
d
p
[
i
+
1
]
[
j
]
[
k
]
=
m
a
x
(
d
p
[
i
+
1
]
[
j
]
[
k
]
,
d
p
[
i
]
[
j
]
[
k
]
)
dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k])
dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k])
当
(
s
i
=
=
t
0
)
(s_{i}==t_{0})
(si==t0)时:
d
p
[
i
+
1
]
[
j
]
[
k
+
1
]
=
m
a
x
(
d
p
[
i
+
1
]
[
j
]
[
k
+
1
]
,
d
p
[
i
]
[
j
]
[
k
]
)
dp[i+1][j][k+1]=max(dp[i+1][j][k+1],dp[i][j][k])
dp[i+1][j][k+1]=max(dp[i+1][j][k+1],dp[i][j][k])。
当
(
s
i
=
=
t
1
)
(s_{i}==t_{1})
(si==t1)时:
d
p
[
i
+
1
]
[
j
]
[
k
]
=
m
a
x
(
d
p
[
i
+
1
]
[
j
]
[
k
]
,
d
p
[
i
]
[
j
]
[
k
]
+
k
)
dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k]+k)
dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k]+k)。
2.修改(需要保证修改次数小于等于
K
K
K):
2.1 把
s
i
s_{i}
si修改为
t
0
t_{0}
t0:
d
p
[
i
+
1
]
[
j
+
1
]
[
k
+
1
]
=
m
a
x
(
d
p
[
i
+
1
]
[
j
+
1
]
[
k
+
1
]
,
d
p
[
i
]
[
j
]
[
k
]
)
dp[i+1][j+1][k+1]=max(dp[i+1][j+1][k+1],dp[i][j][k])
dp[i+1][j+1][k+1]=max(dp[i+1][j+1][k+1],dp[i][j][k])
2.2 把
s
i
s_{i}
si修改为
t
1
t_{1}
t1:
d
p
[
i
+
1
]
[
j
+
1
]
[
k
]
=
m
a
x
(
d
p
[
i
+
1
]
[
j
+
1
]
[
k
]
,
d
p
[
i
]
[
j
]
[
k
]
)
+
k
)
dp[i+1][j+1][k]=max(dp[i+1][j+1][k],dp[i][j][k])+k)
dp[i+1][j+1][k]=max(dp[i+1][j+1][k],dp[i][j][k])+k)
代码
#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
const int N = 2e2+7;
ll dp[N][N][N];
void solve(){
int n,K;cin>>n>>K;
string s,t;cin>>s>>t;
if(t[0]==t[1]){
int cnt0=0;
rp(i,0,n-1) if(s[i]==t[0]) cnt0++;
cnt0+=K;
cnt0=min(cnt0,n);
cout<<cnt0*(cnt0-1)/2<<endl;
return ;
}
memset(dp,-1,sizeof dp);
dp[0][0][0]=0;
rp(i,0,n-1){
rp(j,0,K){
rp(k,0,i){
if(dp[i][j][k]==-1) continue;
if(j+1<=K){
dp[i+1][j+1][k]=max(dp[i+1][j+1][k],dp[i][j][k]+k);
dp[i+1][j+1][k+1]=max(dp[i+1][j+1][k+1],dp[i][j][k]);
}
dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k]);
if(s[i]==t[0]) dp[i+1][j][k+1]=max(dp[i+1][j][k+1],dp[i][j][k]);
else if(s[i]==t[1]) dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k]+k);
}
}
}
ll ans=0;
// rp(i,0,n-1) rp(j,0,K) rp(k,0,i) cout<<i<<" "<<j<<" "<<k<<" "<<dp[i][j][k]<<endl;
rp(i,0,K) rp(j,0,n) ans=max(ans,dp[n][i][j]);
cout<<ans<<endl;
}
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
//debug = 1;
#endif
//time_t beg, end;
//if(debug) beg = clock();
int T=1;
while(T--) solve();
/*
if(debug) {
end = clock();
printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
}
*/
return 0;
}