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; }
对于长度为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; }
假设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!