2015年鄭州大學首屆“玲瓏杯”ACM新生選拔賽題解

C(C++)編譯器

判斷給定的字符串在不在集合中,用字符串比較函數就行了。
代碼:

/*************************************************************************
    > File Name: a.cpp
    > Author: gwq
    > Mail: [email protected] 
    > Created Time: Thu 09 Apr 2015 08:35:46 AM CST
 ************************************************************************/

#include <cmath>
#include <ctime>
#include <cctype>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>

#define INF (INT_MAX / 10)
#define clr(arr, val) memset(arr, val, sizeof(arr))
#define pb push_back
#define sz(a) ((int)(a).size())

using namespace std;
typedef set<int> si;
typedef vector<int> vi;
typedef map<int, int> mii;
typedef pair<int, int> pii;
typedef long long ll;

const double esp = 1e-5;

#define N 100010

int cnt = 8;
char str[N];
const char *mp[] = {"void", "byte", "char", "int", "long", "float",
    "double", "__int64"};

int main(int argc, char *argv[])
{
    while (gets(str) != NULL && strcmp(str, "end") != 0) {
        int flag = 0;
        for (int i = 0; i < 8; ++i) {
            if (strcmp(str, mp[i]) == 0) {
                flag = 1;
                break;
            }
        }
        printf("%s\n", flag ? "Yes" : "No");
    }
    return 0;
}

約瑟夫環

最後一個退出的人是星期幾。注意到每個人都要退出,所以將人數取模就行了。

/*************************************************************************
    > File Name: b.cpp
    > Author: gwq
    > Mail: [email protected] 
    > Created Time: Thu 09 Apr 2015 09:07:45 AM CST
 ************************************************************************/

#include <cmath>
#include <ctime>
#include <cctype>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>

#define INF (INT_MAX / 10)
#define clr(arr, val) memset(arr, val, sizeof(arr))
#define pb push_back
#define sz(a) ((int)(a).size())

using namespace std;
typedef set<int> si;
typedef vector<int> vi;
typedef map<int, int> mii;
typedef pair<int, int> pii;
typedef long long ll;

const double esp = 1e-5;

const char *mp[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
    "Saturday", "Sunday"};

int main(int argc, char *argv[])
{
    int n = 0;
    while (scanf("%d", &n) != EOF && n) {
        n--;
        printf("%s\n", mp[n % 7]);
    }
    return 0;
}

QQ

根據給定的規則計算QQ的價值就行了。鍛鍊代碼能力,注意細節就行了。

/*************************************************************************
    > File Name: c.cpp
    > Author: gwq
    > Mail: [email protected] 
    > Created Time: Thu 09 Apr 2015 09:37:11 AM CST
 ************************************************************************/

#include <cmath>
#include <ctime>
#include <cctype>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>

#define INF (INT_MAX / 10)
#define clr(arr, val) memset(arr, val, sizeof(arr))
#define pb push_back
#define sz(a) ((int)(a).size())

using namespace std;
typedef set<int> si;
typedef vector<int> vi;
typedef map<int, int> mii;
typedef pair<int, int> pii;
typedef long long ll;

const double esp = 1e-5;

#define N 20

ll d1, d2;
char s1[N], s2[N];

ll values(char str[], ll d)
{
    ll ans = d;
    ll len = strlen(str);
    for (int i = 0; i < len; ++i) {
        ans += str[i] - '0';
    }
    int i = 1;
    int cnt = 1;
    while (i <= len) {
        if (str[i] != str[i - 1]) {
            if (cnt > 1) {
                ll x = 1;
                for (int j = 0; j < cnt + 1; ++j) {
                    x *= str[i - 1] - '0' + 1;
                }
                ans += x;
            }
            cnt = 0;
        }
        ++cnt;
        ++i;
    }
    return ans;
}

int main(int argc, char *argv[])
{
    while (scanf("%s%lld%s%lld", s1, &d1, s2, &d2) != EOF) {
        ll l1 = strlen(s1);
        ll l2 = strlen(s2);
        ll v1 = values(s1, d1);
        ll v2 = values(s2, d2);
        if (l1 < l2) {
            v1 = 1;
            v2 = 0;
        } else if (l1 > l2) {
            v1 = 0;
            v2 = 1;
        }
        printf("%s\n", (v1 > v2) ? "First" : ((v1 < v2) ? "Second" : "Equal"));
    }
    return 0;
}

行列式

一個類似行列式的東西,主對角線乘積和減去副對角線上的乘積和。注意結果可能爆int。還有2*2和1*1要特判。
有一個技巧就是使用取模,可能是負數的可以加上n。還有一個方法是將二維數組向右邊複製一份,但數組要開的足夠大。

#include <cstdio>

#define N 15

long long mat[N][N];

int main(void)
{
    int n;
    while (scanf("%d", &n) != EOF) {
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                scanf("%d", &mat[i][j]);
            }
        }
        long long ans = 0;
        for (int i = 0; i < n; ++i) {
            int x = 0;
            int y = i;
            long long tmp = 1;
            for (int j = 0; j < n; ++j) {
                int a = (x + j) % n;
                int b = (y + j) % n;
                tmp *= mat[a][b];
            }
            ans += tmp;
        }
        for (int i = 0; i < n; ++i) {
            int x = i;
            int y = n - 1;
            long long tmp = 1;
            for (int j = 0; j < n; ++j) {
                int a = (x + j + n) % n;
                int b = (y - j + n) % n;
                tmp *= mat[a][b];
            }
            ans -= tmp;
        }
        if (n == 2) {
            ans = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];
        } else if (n == 1) {
            ans = mat[0][0];
        }
        printf("%lld\n", ans);
    }

    return 0;
}

零比特填充-透明傳輸

這個題目用的思路和QQ那道題目一樣,都是求出來連續相同的字符個數,這個要求去掉連續5個1後的零,遇到這個跳過這個字符就行了。

#include <cstdio>
#include <cstring>

#define N 1010

int len;
char str[N], tmp[N];

void check(void)
{
    int cnt = 1;
    int flag = 1;
    for (int i = 1; i <= len; ++i) {
        if (str[i] != str[i - 1]) {
            if (str[i - 1] == '1') {
                if (cnt > 5) {
                    flag = 0;
                    strcpy(str, "Bad luck!");
                    break;
                }
            }
            cnt = 0;
        }
        ++cnt;
    }
    if (flag) {
        cnt = 1;
        strcpy(tmp, str);
        int x = 0;
        for (int i = 1; i <= len; ++i) {
            str[x++] = tmp[i - 1];
            if (tmp[i] != tmp[i - 1]) {
                if (tmp[i - 1] == '1' && cnt == 5) {
                    ++i;
                }
                cnt = 0;
            }
            ++cnt;
        }
        str[x] = '\0';
    }
}

int main(void)
{
    while (scanf("%d%s", &len, str) != EOF) {
        check();
        printf("%s\n", str);
    }
    return 0;
}

數字遊戲

求出來逆序過來的數就行了,然後根據題目描述模擬一下,要記錄中間的結果。

/*************************************************************************
    > File Name: e.cpp
    > Author: gwq
    > Mail: [email protected] 
    > Created Time: Thu 09 Apr 2015 10:54:26 AM CST
 ************************************************************************/

#include <cmath>
#include <ctime>
#include <cctype>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>

#define INF (INT_MAX / 10)
#define clr(arr, val) memset(arr, val, sizeof(arr))
#define pb push_back
#define sz(a) ((int)(a).size())

using namespace std;
typedef set<int> si;
typedef vector<int> vi;
typedef map<int, int> mii;
typedef pair<int, int> pii;
typedef long long ll;

const double esp = 1e-5;

#define N 1000010

int num[N];

int rev(int n)
{
    int ans = 0;
    while (n) {
        ans = ans * 10 +  n % 10;
        n /= 10;
    }
    return ans;
}

int main(int argc, char *argv[])
{
    int n;
    while (scanf("%d", &n) != EOF) {
        int cnt = 0;
        while (n != rev(n)) {
            num[cnt] = n;
            n = n + rev(n);
            ++cnt;
        }
        num[cnt++] = n;
        printf("%d\n", cnt - 1);
        for (int i = 0; i < cnt; ++i) {
            if (i > 0) {
                printf("--->");
            }
            printf("%d", num[i]);
        }
        printf("\n");
    }
    return 0;
}

簡單求值

求表達式的值,是數據結構中棧的基本應用。不過這個可以不用棧,因爲沒有括號,可以從左到右找到第一個*或者/號,計算,替換,一直重複就行了,最後,再計算+或-就行了。下面是棧的版本,用了一個特殊符號,用來表示結束,來計算最後優先級都相同的情況,還有棧爲空的特殊情況。

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

#define N 1010

char op[N], str[N];
int num[N], op_top, num_top;

// 這個用來比較運算符的優先級
int opcmp(char c1, char c2)
{
    if (op_top == 0) {
        return -1;
    }
    char mp[] = "$    +-  */    ^";

    int idx1 = 0;
    int idx2 = 0;
    for (int i = 0; i < strlen(mp); ++i) {
        if (mp[i] == c1) {
            idx1 = i;
        }
        if (mp[i] == c2) {
            idx2 = i;
        }
    }
    if (abs(idx1 - idx2) <= 1) {
        return 0;
    } else {
        return idx1 - idx2;
    }
}

int main(void)
{
    while (scanf("%s", str) != EOF) {
        int len = strlen(str);
        int m = 0;
        op_top = 0;
        num_top = 0;
        str[len] = '$';
        str[len + 1] = '\0';
        for (int i = 0; i <= len; ++i) {
            if (isdigit(str[i])) {
                m = 10 * m + str[i] - '0';
            } else {
                num[num_top++] = m;
                //printf("%d.%c.%c.\n", m, op[op_top - 1], str[i]);
                m = 0;
                while (opcmp(op[op_top - 1], str[i]) >= 0) {
                    char x = op[--op_top];
                    int n1 = num[--num_top];
                    int n2 = num[--num_top];
                    int ans = 0;
                    //printf("%d %c %d\n", n2, x, n1);
                    switch (x) {
                        case '+': ans = n2 + n1; break;
                        case '*': ans = n2 * n1; break;
                        case '-': ans = n2 - n1; break;
                        case '/': ans = n2 / n1; break;
                    }
                    num[num_top++] = ans;

                }
                op[op_top++] = str[i];
            }
        }
        printf("%d\n", num[num_top - 1]);
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章