Codeforces Round #667 (Div. 3)

题目:A. Yet Another Two Integers Problem
题意:在这里插入图片描述直接差值模拟。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef double ld;
typedef pair<ll,ll> PP;
const int MAXN=2e3+4;
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int a,b,ans=0;;
        scanf("%d %d",&a,&b);
        int temp=abs(a-b);
        ans+=temp/10;temp%=10;
        if(temp) ++ans;
        printf("%d\n",ans);
    }
    return 0;
}
 

题目:B. Minimum Product
题意:给定四个整数a,b,x,y,已知 a > = x , b > = y a>=x,b>=y a>=x,b>=y。n次操作每次让a或者b减1,问 a ∗ b a*b ab的最小值。

分情况讨论 n > = ( a − x ) + ( b − y ) n>=(a-x)+(b-y) n>=(ax)+(by)最小值就是 x ∗ y x*y xy。 设 ( a − k ) ∗ ( b − ( n − k ) ) , 并 且 ( k < = a − x , n − k < = ( b − y ) ) (a-k)*(b-(n-k)),并且(k<=a-x ,n-k<=(b-y)) (ak)(b(nk)),(k<=axnk<=(by)),可知 ( a − k ) ∗ ( b − ( n − k ) ) (a-k)*(b-(n-k)) (ak)(b(nk))函数开口向上,直接判断端点情况。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef double ld;
ll a,b,x,y,n;
ll solve(ll k) {
    return ((a-k)*(b-n+k));
}
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%lld %lld %lld %lld %lld",&a,&b,&x,&y,&n);
        if(n>=((a-x)+(b-y))) {
            printf("%lld\n",x*y);
        }
        else {
            ll up=max(min(a-x,n),1ll*0);
            ll down=min(n,max(1ll*0,y+n-b));
            printf("%lld\n",min(solve(up),solve(down)));
        }
    }
    return 0;
}

题目:C. Yet Another Array Restoration
题意:需要你构成一个等差数组,长度为n,n个数都不相同,让最大的数最小,输出数组。

给定了 x < y xx<y,那么这两个数字一定是数组中的某一个,直接枚举公差。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef double ld;
typedef pair<ll,ll> PP;
const int MAXN=2e3+4;
int a[100];
int ans[100];
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int n,x,y;
        scanf("%d %d %d",&n,&x,&y);
        if(n==2) {
            printf("%d %d\n",x,y);
            continue;
        }
        if(y-x-1==n-2) {
            for(int i=x;i<=y;++i) {
                printf("%d ",i);
            }
            printf("\n");
            continue;
        }
        for(int d=1;d<=y-x;d++) {
            if( (y-x)%d!=0 )
                continue;
            int temp=y%d;
            if(!temp) temp+=d;
            if(temp+(n-1)*d<=y && x+(n-1)*d>=y ) {
                for(int j=y,cnt=1;cnt<=n;j-=d) {
                    printf("%d ",j); cnt++;
                }
                break;
            }
            else  {
                if(temp+(n-1)*d>y) {
                    for(int j=temp,cnt=1;cnt<=n;j+=d) {
                        printf("%d ",j); ++cnt;
                    }
                    break;
                }
            }
        }
        printf("\n");
    }
    return 0;
}

题目:D. Decrease the Sum of Digits
题意:每次可以让n加1,问最小的操作次数让n的所有位数之和小于等于s。

贪心,每次都处理低位的数字,直接给n进位减小各位数字总和,考虑极端情况有没有直接改变某一位成功的,比如711 和 3,从低位开始时289,直接是300,以此类推,从低位模拟即可。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef double ld;
typedef pair<ll,ll> PP;
int book[30];
ll solve(ll x) {
    ll ans=0;
    while(x) {
        ans+=x%10;
        x/=10;
    }
    return ans;
}
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        ll n,s;
        scanf("%lld %lld",&n,&s);
        if(solve(n)<=s) {
            printf("0\n");
            continue;
        }
        ll ft=1,ans=0;
        for(int i=1;i<=20;++i) {
            ll now=(n/ft)%10;
            if(now==0) {
                ft*=10;
                continue;
            }
            ll temp=ft*(10-now);
            n+=temp;
            ans+=temp;
            ft*=10;
            if(solve(n)<=s) {
                break;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

题目:E. Two Platforms
题意:给定n个点的坐标,让你找到两个平台即长度为k的恒定的y, x 2 − x 1 = k x2-x1=k x2x1=k,问x在[x1,x2]区间的点数最多有多少。
可以知道和y并没有什么关系,sort一下n个点的x坐标,二分找右边第一个大于 x + k x+k x+k的点,找左边 x 0 = = x x0==x x0==x的点,预处理出以x点为左端点长度为k的平台的个数。
MAX[]数组维护 x + k x+k x+k之后最大的平台承载的点个数。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef double ld;
typedef pair<ll,ll> PP;
int x[200010];
int book[200010];
int MAX[200010];
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int n,k;
        scanf("%d %d",&n,&k);
        for(int i=1;i<=n;++i)
            scanf("%d",&x[i]);
        for(int i=1;i<=n;++i) {
            int o;scanf("%d",&o);
        }
        sort(x+1,x+1+n);
        for(int i=1;i<=n;++i) {
            int temp=x[i]+k;
            int posr=upper_bound(x+1,x+1+n,x[i]+k)-x;
            int posl=lower_bound(x+1,x+1+n,x[i])-x;
            book[i]=posr-i+i-posl;
        }
        MAX[n+1]=MAX[n+2]=0;
        for(int i=n;i>=1;--i) {
            MAX[i]=max(MAX[i+1],book[i]);
        }
        int ans=1;
        for(int i=1;i<=n;++i) {
            int pos=upper_bound(x+1,x+1+n,x[i]+k)-x;
            ans=max(ans,MAX[pos]+book[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

题目:F. Subsequences of Length Two
题意:长度为n的字符串s,每一次操作可以改变字符为a-z任意一个,不超过k次,问最多s中能有几个子序列为t字符串。

直接划分状态集合,dp[i][j]:为前i个字符改变j次的最大值,我们还需要知道贡献的计算,再开一维表示t[0]的个数,直接进行转移。注意一下t[0]=t[1]的时候即贡献了t[0]数量,也给答案贡献了。
代码写的比较丑见谅。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
typedef double ld;
typedef pair<ll,ll> PP;
char S[222],T[3];
int dp[210][208][207];//前i个字符串 改变了j次  k个T[0]的个数 的 最大贡献
int main() {
    memset(dp,-1,sizeof(dp));
    int n,k;
    int ans=0;
    scanf("%d %d",&n,&k);
    scanf("%s",S+1); scanf("%s",T);
        for(int i=0;i<=n;++i) {
            for(int j=0;j<=k;++j)
                if(i==0)
                dp[i][0][0]=0;
            else dp[i][j][0]=0;
    }
    for(int i=1;i<=n;++i) {
        for(int j=0;j<=k;++j) {
            for(int kk=0;kk<=i;++kk) {
                if(dp[i-1][j][kk]!=-1) {
                    dp[i][j][kk]=max(dp[i][j][kk],dp[i-1][j][kk]);
                }
                if(T[0]==T[1]) {
                    if(S[i]==T[0]) {
                        if(dp[i-1][j][kk]!=-1)
                        dp[i][j][kk+1]=max(dp[i][j][kk+1],dp[i-1][j][kk]+kk);
                    }
                    else {
                        if(j<k) {
                            if(dp[i-1][j][kk]!=-1)
                            dp[i][j+1][kk+1]=max(dp[i][j+1][kk+1],dp[i-1][j][kk]+kk);
                        }
                    }
                    ans=max(dp[i][j][kk],ans);
                    continue;
                }
                if(S[i]==T[0]) {
                    if(dp[i-1][j][kk]!=-1)
                    dp[i][j][kk+1]=max(dp[i][j][kk+1],dp[i-1][j][kk]);
                }
                else {
                    if(j+1<=k) {
                            if(dp[i-1][j][kk]!=-1)
                        dp[i][j+1][kk+1]=max(dp[i][j+1][kk+1],dp[i-1][j][kk]);
                    }
                }
                if(S[i]==T[1]) {
                        if(dp[i-1][j][kk]!=-1&&kk<i)
                    dp[i][j][kk]=max(dp[i][j][kk],dp[i-1][j][kk]+kk);
                }
                else {
                    if(j+1<=k) {
                        if(dp[i-1][j][kk]!=-1&&kk<i)
                        dp[i][j+1][kk]=max(dp[i][j+1][kk],dp[i-1][j][kk]+kk);
                    }
                }
                ans=max(dp[i][j][kk],ans);
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(Codeforces Round #667 (Div. 3))