UCF Local Programming Contest 2012(Practice)

A

DP。两个区间合成一个区间的代价为两个区间分别取每个区间深度与长度最大值,它们的乘积*100即为代价。
\(dp[l][r] = dp[l][k] + dp[k+1][r] + 100 * min(d[l][k], len[l][k]) * min(d[k+1][r], len[k+1][r])\)
其中d[][]与len[][]数组可以预处理出来,d数组即为每个区间深度的最大值,len数组即为每个区间长度之和。
预处理的复杂度为\(O(n^2)\)。dp的复杂度为\(O(n^3)\)

代码

#include <bits/stdc++.h>
using namespace std;
int T, len[21][21], Max[21][21], f[21][21];
struct node {
    int x, y;
}A[30], B[30];
int main() {
    scanf("%d", &T);
    for(int t=1; t<=T; ++t) {
        int n; scanf("%d", &n);
        for(int i=1; i<=n; ++i) scanf("%d%d", &A[i].x, &A[i].y);
        for(int l=1; l<=n; ++l) {
            len[l][l] = A[l].x; Max[l][l] = A[l].y;
            for(int r=l+1; r<=n; ++r) {
                len[l][r] = len[l][r-1] + A[r].x;
                Max[l][r] = max(Max[l][r-1], A[r].y);
            }
        }
        for(int l=1; l<=n; ++l) {
            f[l][l] = 0;
            for(int r=l+1; r<=n; ++r) f[l][r] = 2147483647;
        }
        for(int Len=2; Len<=n; ++Len) {
            for(int l=1; l+Len-1<=n; ++l) {
                int r = l+Len-1;
                for(int k=l; k<r; ++k) {
                    f[l][r] = min(f[l][r], f[l][k]+f[k+1][r]+100*min(len[l][k], Max[l][k])*min(len[k+1][r], Max[k+1][r]));
                }
            }
        }
        printf("The minimum cost for lot #%d is $%lld.\n\n", t, f[1][n]);
    }
    return 0;
}

B

水题。直接统计两个字符串中每个字符出现的次数即可,再从Z到A进行比较。

代码

#include <bits/stdc++.h>
using namespace std;
int T, size1, size2;
int num1[50], num2[50];
string s1, s2;
int main() {
    scanf("%d", &T);
    for(int t=1; t<=T; ++t) {
        cin >> s1 >> s2;
        size1 = s1.size();
        size2 = s2.size();
        memset(num1, 0, sizeof(num1));
        memset(num2, 0, sizeof(num2));
        for(int i=0; i<size1; ++i) num1[s1[i]-'a']++;
        for(int i=0; i<size2; ++i) num2[s2[i]-'a']++;
        int ans = 0;
        for(int i='z'-'a'; i>=0; --i) {
            if(num1[i] > num2[i]) {ans = 1; break;}
            else if(num1[i] < num2[i]) {ans = 2; break;}
        }
        printf("Data set #%d: ", t);
        if(!ans) cout << "The two strings are the same age" << endl << endl;
        else if(ans == 1) cout << "First string is older" << endl << endl;
        else if(ans == 2) cout << "First string is younger" << endl << endl;
    }
    return 0;
}

C

重点在处理空格上,理解了上下两行之间空格的个数即可。

代码

#include <bits/stdc++.h>
using namespace std;
int T, num[10005];
int solve(int x) {
    int re = 0;
    while(x) {
        x /= 10;
        ++re;
    }
    return re;
}
int main() {
    scanf("%d", &T);
    for(int t=1; t<=T; ++t) {
        int n; scanf("%d", &n);
        memset(num, 0, sizeof(num));
        for(int i=1; i<=n; ++i) {
            int x, y; scanf("%d%d", &x, &y);
            num[x] += y;
        }
        printf("Prime Factorization #%d: \n", t);
        for(int i=1; i<=10000; ++i) if(num[i]) {
            int j=solve(i);
            for(int k=1; k<=j; ++k) printf(" ");
            printf("%d", num[i]);
        }
        printf("\n");
        int k = 0;
        for(int i=1; i<=10000; ++i) if(num[i]) {
            for(int j=1; j<=k; ++j) printf(" ");
            printf("%d", i);
            k = solve(num[i]);
        }
        printf("\n\n");
    }
    return 0;
}

D

模拟题,重点在理解题意上,而且由于是英文题,所以对题意的理解又上了一个难度。

代码

#include <bits/stdc++.h>
using namespace std;
int n, m;
struct node{
    int val, flag;
}A[60];
int main() {
    int T=0;
    while(~scanf("%d%d", &n, &m)) {
        if(!n && !m) break;
        printf("Program %d\n", ++T);
        int ans = 0, now = 1;
        for(int i=1; i<=n; ++i) A[i].val = A[i].flag = 0;
        for(int i=1; i<=m; ++i) {
            int x; scanf("%d", &x); bool fl = 0;
            for(int j=1; j<=n; ++j) if(A[j].val == x) {
                A[j].flag = 1;
                printf("Access page %d in cell %d.\n", x, j); fl = 1;
                break;
            }
            if(fl) continue;
            while(A[now].flag == 1) {
                A[now].flag = 0;
                now = now + 1;
                if(now == n+1) now = 1;
            }
            A[now].val = x; A[now].flag = 1;
            printf("Page %d loaded into cell %d.\n", x, now);
            now = now + 1;
            if(now == n+1) now = 1;
            ++ans;
        }
        printf("There are a total of %d page faults.\n\n", ans);
    }
    return 0;
}

G

仔细分析题意,发现S与T唯一的区别在于S后面可以跟空字符。只要有a就必须有一个b跟它对应,而对于c即可当作S也可以当作T。那么你只需要去报a与b相对应,并且ab之间的必须为T即不能为空就行。
需要注意的是数据中存在非abc以为的字符,这种也属于不合法。

代码

#include <bits/stdc++.h>
using namespace std;
int T, pel[60];
string s;
bool pt(int l, int r) {
    if(r < l) return 0;
    for(int i=l; i<=r; ++i) if(s[i] == 'a') {
        if(pt(i+1, pel[i]-1) == 0) return 0;
    }
    return 1;
}
int main() {
    scanf("%d", &T);
    for(int t=1; t<=T; ++t) {
        cin >> s;
        printf("Pattern %d: ", t);
        int sz = s.size();
        int re[60]; re[0] = 0;
        bool fl = 0;
        for(int i=0; i<sz; ++i) {
            if(s[i] != 'a' && s[i] != 'b' && s[i] != 'c') {
                fl = 1;
            }
        }
        if(fl) {
            printf("Still Looking.\n\n");
            continue;
        }
        for(int i=0; i<sz; ++i) if(s[i] == 'a') {
            re[++re[0]] = i;
        }
        else if(s[i] == 'b') {
            if(re[0] == 0) {
                fl = 1; break;
            }
            pel[i] = re[re[0]];
            pel[pel[i]] = i;
            --re[0];
        }
        if(re[0]) fl = 1;
        if(fl) {
            printf("Still Looking.\n\n");
            continue;
        }
        for(int i=0; i<sz; ++i) if(s[i] == 'a') {
            if(!pt(i+1, pel[i]-1)) {fl = 1; break;}
        }
        if(fl) {
            printf("Still Looking.\n\n");
        }
        else {
            printf("More aliens!\n\n");
        }
    }
    return 0;
}

H

送分题。

代码

#include <bits/stdc++.h>
using namespace std;
#define LL long long
int T;
LL a[5];
int main() {
    scanf("%d", &T);
    for(int t=1; t<=T; ++t) {
        for(int i=1; i<=3; ++i) scanf("%lld", &a[i]);
        printf("Data set #%d:\n   ", t);
        printf("Original order: %lld %lld %lld", a[1], a[2], a[3]);
        printf("\n   Smallest to largest: ");
        sort(a+1, a+4);
        printf("%lld %lld %lld", a[1], a[2], a[3]);
        printf("\n\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Samle/p/12437292.html