ccf-csp 2019春季真题题解


  1. 小中大
    ccf-csp 2019春季真题题解_第1张图片
    ccf-csp 2019春季真题题解_第2张图片

代码:

#include 
#include 

using namespace std;

const int N = 100010;
int arr[N];

int main(){
    int n, a, b, c;

    cin >> n;
    for(int i = 0; i < n; i ++)
        cin >> arr[i];

    a = arr[0];
    c = arr[n - 1];
    if(a < c)
        swap(a, c);
    if(n & 1)
        b = 2 * arr[n / 2];
    else
        b = arr[n / 2] + arr[n / 2 - 1];

    cout << a << " ";
    if(b & 1)
        printf("%.1lf ", b / 2.0);
    else
        printf("%d ", b / 2);
    cout << c << endl;
    return 0;
}

  1. 二十四点
    ccf-csp 2019春季真题题解_第3张图片
    ccf-csp 2019春季真题题解_第4张图片

代码:

#include 
#include 
#include 
#include 
#include 

using namespace std;

stack<int> num;
stack<char> op;

void eval()
{
    int b = num.top(); num.pop();
    int a = num.top(); num.pop();
    char c = op.top(); op.pop();
    int x;
    if (c == '+') x = a + b;
    else if (c == '-') x = a - b;
    else if (c == 'x') x = a * b;
    else
    {
        if (a * b >= 0) x = a / b;
        else  // 向下取整。C++中a/b是向零取整
        {
            if (a % b == 0) x = a / b;
            else x = a / b - 1;
        }
    }
    num.push(x);
}

int main()
{
    unordered_map<char, int> pr;
    pr['+'] = pr['-'] = 1;
    pr['x'] = pr['/'] = 2;
    int n;
    cin >> n;
    while (n -- )
    {
        string str;
        cin >> str;
        num = stack<int>();
        op = stack<char>();
        for (auto c: str)
            if (c >= '0' && c <= '9') num.push(c - '0');
            else
            {
                while (op.size() && pr[op.top()] >= pr[c]) eval();
                op.push(c);
            }
        while (op.size()) eval();
        if (num.top() == 24) puts("Yes");
        else puts("No");
    }
    return 0;
}

  1. 201903-3
    ccf-csp 2019春季真题题解_第5张图片
    ccf-csp 2019春季真题题解_第6张图片
    ccf-csp 2019春季真题题解_第7张图片
    ccf-csp 2019春季真题题解_第8张图片
    ccf-csp 2019春季真题题解_第9张图片

代码:

#include 
#include 
#include 

using namespace std;

typedef unsigned int UI;
const int N = 1010, M = 40 * 1024 * 8 + 10;

int n, s, l;
UI disk[N][M / 8];
bool st[N];
char str[M];
int len;

inline UI get(char c)
{
    if (c <= '9') return c - '0';
    return c - 'A' + 10;
}

inline char get(UI x)
{
    if (x <= 9) return x + '0';
    return x - 10 + 'A';
}

inline string u2s(UI x)
{
    string res;
    for (int i = 7; i >= 0; i -- )
        res += get(x >> (i << 2) & 15);
    return res;
}

inline int get_real_col(int r, int c)
{
    r %= n;
    r = n - 1 - r;
    return (r + 1 + c) % n;
}

int main()
{
    scanf("%d%d%d", &n, &s, &l);
    for (int u = 0; u < l; u ++ )
    {
        int k;
        scanf("%d", &k);
        getchar();
        fgets(str, M, stdin);
        int sz = strlen(str) - 1;
        for (int i = 0; i < sz; i += 8)
        {
            UI x = 0;
            for (int j = 0; j < 8; j ++ )
                x = (x << 4) + get(str[i + j]);
            disk[k][i >> 3] = x;
        }
        st[k] = true;
        len = max(len, sz >> 3);
    }

    int m;
    scanf("%d", &m);
    while (m -- )
    {
        int b;
        scanf("%d", &b);
        if (b >= len * (n - 1)) puts("-");
        else
        {
            int k = b / s;
            int row = k / (n - 1), col = get_real_col(row, k % (n - 1));
            int r = row * s + b % s;
            if (st[col])
                puts(u2s(disk[col][r]).c_str());
            else if (l == n - 1)
            {
                UI x = 0;
                for (int i = 0; i < n; i ++ ) x ^= disk[i][r];
                puts(u2s(x).c_str());
            }
            else puts("-");
        }
    }
    return 0;
}

作者:yxc
链接:https://www.acwing.com/activity/content/code/content/905793/

  1. 消息传递接口
    ccf-csp 2019春季真题题解_第10张图片
    ccf-csp 2019春季真题题解_第11张图片
    ccf-csp 2019春季真题题解_第12张图片

代码:

#include 
#include 
#include 

using namespace std;

const int N = 10010;
//pos为遍历到当前行的位置 w为当前行限制的长度
int pos[N], w[N], t, n;
//记录 R/S 的进程i对应的行 -1代表没出现
vector<int> map[2][N];
//记录输入
typedef pair<int, int> PII;
vector<PII> arr[N];

bool check() {
    for (int i = 0; i < n; i++)
        if (pos[i] < w[i] && pos[i] < arr[i].size())
            return true;
    return false;
}

int main() {
    cin >> t >> n;
    getchar();

    while (t--) {
        //初始化
        for (int i = 0; i < n; i++) {
            map[0][i].clear();
            map[1][i].clear();
            pos[i] = 0;
            arr[i].clear();
        }

        //处理输入
        for (int i = 0; i < n; i++) {
            string s;
            int pos = 0;

            getline(cin, s);
            while (pos < s.length()) {
                bool op = s[pos] == 'R';
                ++ pos;
                int len = 0;
                while(pos + len < s.length() && s[pos + len] != ' ')
                    ++ len;
                int a = stoi(s.substr(pos, len));
                pos += len + 1;
                arr[i].emplace_back(op, a);
            }
            w[i] = 1;
        }
        //检查有无可用的响应
        while (check()) {
            //遍历n行
            for (int i = 0; i < n; i++) {
                //遍历每个可用的响应
                for (; pos[i] < w[i] && pos[i] < arr[i].size(); ++pos[i]) {
                    PII cur = arr[i][pos[i]];
                    //没有对应的请求
                    if (!map[!cur.first][i].empty()) {
                        int t = map[!cur.first][i].back();
                        //pop掉元素
                        map[!cur.first][i].pop_back();
                        //放宽限制的长度
                        ++w[t];
                        ++w[i];
                    } else {
                        //记录元素
                        map[cur.first][cur.second].push_back(i);
                    }
                }
            }

        } //while
        bool op = true;
        for (int i = 0; i < n; i++)
            if (pos[i] < arr[i].size() || map[0][i].size() || map[1][i].size())
                op = false;
        if (op)
            cout << "0" << endl;
        else
            cout << "1" << endl;
    }
    return 0;
}

  1. 317号子任务
    ccf-csp 2019春季真题题解_第13张图片
    ccf-csp 2019春季真题题解_第14张图片
    ccf-csp 2019春季真题题解_第15张图片

本题使用dijkstra会超时,在稀疏图中spfa更快,故使用spfa求最短路,而dijkstra稳定。
代码:

#include 
#include 
#include 
#include 

using namespace std;

const int N = 10010;

int head[N], ver[2 * N], nxt[2 * N], edge[2 * N], dist[N][1010], cnt = 0;
bool is[N], vis[N];
int n, m, k;

void add(int a, int b, int c) {
    ver[++cnt] = b;
    edge[cnt] = c;
    nxt[cnt] = head[a];
    head[a] = cnt;
}

//spfa算法
void spfa(int st) {
    memset(vis, false, sizeof(vis));

    queue<int> Q;

    Q.push(st);
    dist[st][cnt] = 0;
    vis[st] = true;
    while (!Q.empty()) {
        int cur = Q.front();
        Q.pop();
        vis[cur] = false;
        for (int i = head[cur]; i; i = nxt[i]) {
            int u = ver[i];
            if (dist[u][cnt] > dist[cur][cnt] + edge[i]) {
                dist[u][cnt] = dist[cur][cnt] + edge[i];
                if (!vis[u])
                    Q.push(u);
            }
        }
    }
}

int main() {
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= n; i++)
        scanf("%d", &is[i]);

    while (m--) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
        add(b, a, c);
    }

    memset(dist, 0x3f, sizeof(dist));
    cnt = 0;
    for (int i = 1; i <= n; i++)
        //对特殊节点使用spfa
        if (is[i]) {
            spfa(i);
            ++cnt;
        }

    for (int i = 1; i <= n; i++) {
        //排序后取前面小的k个
        sort(dist[i], dist[i] + cnt);
        int ans = 0, t = 0;
        for (int j = 0; j < cnt && t < k; j++)
            if (dist[i][j] == 0x3f3f3f3f)
                break;
            else
                ans += dist[i][j], ++t;
        printf("%d\n", ans);
    }

    return 0;
}

更多历年题解戳这里:ccf-csp 历年真题题解

你可能感兴趣的:(备战2021春,ccf-csp,C++,算法,数据结构,ccf,csp)