2012年"新秀杯"程序设计比赛——现场热身赛参考题解

P.S. 这里只给出了前三题的参考题解(新添加的)。


比赛链接:http://acm.swjtu.edu.cn/JudgeOnline/showcontest?contest_id=1130

参赛对象:大一、大二

比赛时间:2012年11月17日 14:00——17:00


参考题解:

【A题:最大矩阵和】

预处理每一列中,第X行到第Y行的和,然后沿着列方向DP即可。

#include<cstdio>
#include<algorithm>

using namespace std;

const int maxN = 100 + 2;

int N, M;
int A[maxN][maxN];

int gao()
{
    for(int i = 1, j; i < N; i ++)
        for(j = 0; j < M; j ++)
            A[i][j] += A[i - 1][j];

    int ans = A[0][0];
    for(int i = 0; i < N; i ++) {
        for(int j = i; j < N; j ++) {
            int tmp = A[j][0]; if( i ) tmp -= A[i - 1][0];
            ans = max(ans, tmp);
            for(int k = 1; k < M; k ++) {
                int sub = A[j][k]; if( i ) sub -= A[i - 1][k];
                tmp = max(sub, sub + tmp);
                ans = max(ans, tmp);
            }
        }
    }

    return ans;
}

int main()
{
    while( scanf("%d %d", &N, &M) == 2 ) {
        for(int i = 0, j; i < N; i++)
            for(j = 0; j < M; j++)
                scanf("%d", A[i] + j);
        printf("%d\n", gao());
    }
    return 0;
}

【B题:Easy Count】

对于长度为L的字符串,首先利用排列组合可求出其前面的字符串,然后,对于长度为L的字符串,可以统计出大于该字符串的字符串个数,最后,利用互补性,求解即可。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

const int maxN = 26 + 2;

char str[maxN]; int C[maxN][maxN];

int main()
{
    memset(C, 0, sizeof(C));
    for(int i = 0; i <= 26; i++) {
        for(int j = 0; j <= i; j ++) {
            if( j == 0 || j == i ) C[i][j] = 1;
            else C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
        }
    }

    while( scanf("%s", str) == 1 ) {
        int L = strlen(str); int ans = 0;
        for(int i = 1; i < L; i ++) ans += C[26][i];

        int T = C[26][L]; int P = 0; int maxC = 0;
        for(int i = 0; i < L; i ++) {
            maxC = max(maxC, str[i] - 'a');
            if( 25 - maxC >= L - i ) P += C[25 - maxC][L - i];
        }

        printf("%d\n", T - P + ans);
    }

    return 0;
}

【C题:Easy String】

假设F[ i, j ] 表示从字符串第 i 个字符到第 j 个字符是否满足条件,则有:

F[ i, j ] = ( F[ i, k ] && F[ k+1, j ] ) || ( str[ i ] == str[ j ] && F[ i+1, j-1 ] )

利用回溯法,即可求解。

#include<cstdio>
#include<cstring>

const int maxN = 100 + 2;

char str[maxN]; int L;
int h[maxN][maxN];

int dfs(int L, int R)
{
    if( L == R )
        return (h[L][R] = 0);

    if( L + 1 == R && str[L] == str[R])
        return (h[L][R] = 1);

    if( L + 1 == R )
        return (h[L][R] = 0);

    if( h[L][R] != -1 )
        return h[L][R];

    h[L][R] = 0;

    for(int K = L; K <= R; K ++)
        if( dfs(L, K) && dfs(K + 1, R) ) {
            h[L][R] = 1; break;
        }

    if( h[L][R] == 0 && (str[L] == str[R]) )
        h[L][R] = dfs(L + 1, R - 1);

    return h[L][R];
}

int main()
{
    while( scanf("%s", str) == 1 ) {
        L = strlen(str);
        for(int i = 0, j; i < L; i ++)
            for(j = 0; j < L; j ++)
                h[i][j] = -1;
        printf("%s\n", dfs(0, L - 1) ? "Yes" : "No");
    }
    return 0;
}

Thank you for your reading!

你可能感兴趣的:(2012年"新秀杯"程序设计比赛——现场热身赛参考题解)