Codeforces Round #667 (Div. 3)——解题报告

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) (10cur)% 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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值