//目录

Codeforces Round #513

A. Phone Numbers

题意:给一些数字,每个电话号码以8开头,11位,求最多组成多少个号码,重复累加。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 105;
char str[maxn];

int main() {
    int n;
    scanf("%d%s",&n,str);
    int cnt = 0;
    for(int i = 0; i < strlen(str); i++) {
        if(str[i]=='8') cnt++;
    }

    while(cnt) {
        if((n-cnt)>=cnt*10) break;
        cnt--;
    }

    cout<<cnt<<endl;


    return 0;
}
View Code

 

B. Maximum Sum of Digits

题意:给一个数n,找出 a,b,使得 a + b = n,S(a) + S(b) 最大,其中S(x) 是个位数字之和。

分析:从案例中可知,先尽可能出9

#include <bits/stdc++.h>

using namespace std;

char str[15];

int calc(long long x) {
    int res = 0;
    while(x) {
        res += x%10;
        x/=10;
    }
    return res;
}

int main() {
    scanf("%s",str);
    long long x= 0;
    for(int i = 0; i < (int)strlen(str); i++)
        x = x*10 + str[i] - '0';

    long long a;
    if(str[0]>'1') {
        a = (str[0]-'0')-1;
        for(int i = 1; i < (int)strlen(str); i++) {
            a = a * 10 + 9;
        }
    }
    else {
        a = 0;
        for(int i = 1; i < (int)strlen(str); i++) {
            a = a * 10 + 9;
        }
    }

    long long b = x - a;
    printf("%d\n",calc(a)+calc(b));

    return 0;
}
View Code

 

C. Maximum Subrectangle

分析:最大子矩阵,矩阵是由两个向量计算而成,子矩阵和=两个向量部分乘积。计算a,b向量,连续 i 个数字最小和,这样组成的子矩阵和最小,然后枚举子矩阵长宽。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 2000+5;
int a[maxn],b[maxn],min1[maxn],min2[maxn];

int main() {

    int n,m;
    scanf("%d%d",&n,&m);

    for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
    for(int i = 1; i <= m; i++) scanf("%d",&b[i]);
    int x;  scanf("%d",&x);

    for(int i = 1; i <= n; i++) {
        int sum = 0;
        for(int j = 1; j <= i; j++) sum+=a[j];
        min1[i] = sum;
        for(int j = i+1; j <= n; j++) {
            sum-=a[j-i];
            sum+=a[j];
            min1[i] = min(min1[i],sum);
        }
    }

    for(int i = 1; i <= m; i++) {
        int sum = 0;
        for(int j = 1; j <= i; j++) sum+=b[j];
        min2[i] = sum;
        for(int j = i+1; j <= m; j++) {
            sum-=b[j-i];
            sum+=b[j];
            min2[i] = min(min2[i],sum);
        }
    }

    int ans = 0;
    for(int i = 1; i<= n; i++) {
        for(int j = 1; j <= m; j++) {
            if((long long)min1[i]*min2[j]<=x)
                ans = max(ans,i*j);
        }
    }

    cout<<ans<<endl;

    return 0;
}
View Code

 

posted @ 2018-10-12 16:17  小草的大树梦  阅读(239)  评论(0编辑  收藏  举报