ccf-csp 2019冬季真题题解


  1. 报数
    ccf-csp 2019冬季真题题解_第1张图片
    ccf-csp 2019冬季真题题解_第2张图片

代码:

#include 

using namespace std;

int main(){
    int n, i = -1;
    int cnt[4] = {0};

    cin >> n;
    while(n){
        i ++;
        if((i + 1) % 7 == 0 || (to_string(i + 1).find('7') != -1))
            cnt[i % 4] ++;	//跳过报数
        else
            n --;
    }
    for(int i = 0; i < 4; i ++)
        cout << cnt[i] << endl;
    return 0;
}

  1. 回收站选址
    ccf-csp 2019冬季真题题解_第3张图片
    ccf-csp 2019冬季真题题解_第4张图片
    ccf-csp 2019冬季真题题解_第5张图片

代码:

#include 

using namespace std;
const int MAXN = 1010;
typedef pair<int, int> PII;
PII arr[MAXN];
//定义八个方向
int fx[8][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
int n;
//检查是否有这个坐标
bool check(int x, int y){
    for(int i = 0; i < n; i ++)
        if(arr[i].first == x && arr[i].second == y)
            return true;
    return false;
}

int main(){
    int a, b;
    int ans[5] = {0};

    cin >> n;
    for(int i = 0; i < n; i ++){
        cin >> a >> b;
        arr[i].first = a;
        arr[i].second = b;
    }

    for(int i = 0; i < n; i ++){
        bool op = true;
        //判断四个基本方向
        for(int j = 0; j < 4; j ++)
            if(!check(arr[i].first + fx[j][0], arr[i].second + fx[j][1]))
                op = false;
        if(!op)
            continue;
        int cnt = 0;
        //判断四个扩展方向
        for(int j = 4; j < 8; j ++)
            cnt += check(arr[i].first + fx[j][0], arr[i].second + fx[j][1]);
        ans[cnt] ++;
    }
    for(int i = 0; i < 5; i ++)
        cout << ans[i] << endl;
    return 0;
}

  1. 化学方程式
    ccf-csp 2019冬季真题题解_第6张图片
    ccf-csp 2019冬季真题题解_第7张图片
    ccf-csp 2019冬季真题题解_第8张图片
    ccf-csp 2019冬季真题题解_第9张图片

代码:

#include 
#include 
#include 
#include 

#define x first
#define y second

using namespace std;

typedef unordered_map<string, int> MPSI;

MPSI dfs(string& str, int& u)
{
    MPSI res;
    while (u < str.size())
    {
        if (str[u] == '(')
        {
            u ++ ;  // 过滤掉 '('
            auto t = dfs(str, u);
            u ++ ;  // 过滤掉 ')'
            int cnt = 1, k = u;
            while (k < str.size() && isdigit(str[k])) k ++ ;
            if (k > u)
            {
                cnt = stoi(str.substr(u, k - u));
                u = k;
            }
            for (auto c: t)
                res[c.x] += c.y * cnt;
        }
        else if (str[u] == ')') break;
        else
        {
            int k = u + 1;
            while (k < str.size() && str[k] >= 'a' && str[k] <= 'z') k ++ ;
            auto key = str.substr(u, k - u);
            u = k;
            int cnt = 1;
            while (k < str.size() && isdigit(str[k])) k ++ ;
            if (k > u)
            {
                cnt = stoi(str.substr(u, k - u));
                u = k;
            }
            res[key] += cnt;
        }
    }
    return res;
}

MPSI work(string str)
{
    MPSI res;
    for (int i = 0; i < str.size(); i ++ )
    {
        int j = i + 1;
        while (j < str.size() && str[j] != '+') j ++ ;
        auto item = str.substr(i, j - i);
        i = j;
        int cnt = 1, k = 0;
        while (k < item.size() && isdigit(item[k])) k ++ ;
        if (k) cnt = stoi(item.substr(0, k));
        auto t = dfs(item, k);
        for (auto c: t)
            res[c.x] += c.y * cnt;
    }
    return res;
}

int main()
{
    int n;
    cin >> n;
    while (n -- )
    {
        string str;
        cin >> str;
        int k = str.find('=');
        auto left = work(str.substr(0, k)), right = work(str.substr(k + 1));
        if (left == right) puts("Y");
        else puts("N");
    }
    return 0;
}

  1. 区块链
    ccf-csp 2019冬季真题题解_第10张图片
    ccf-csp 2019冬季真题题解_第11张图片
    ccf-csp 2019冬季真题题解_第12张图片
    ccf-csp 2019冬季真题题解_第13张图片
    ccf-csp 2019冬季真题题解_第14张图片
    ccf-csp 2019冬季真题题解_第15张图片

代码:

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef vector<int> VI;
const int N = 510, M = 20010;

int n, m, w, Q;
int h[N], e[M], ne[M], idx;
vector<VI> g;
int node[N];

struct Op
{
    int t, id, pid, hid;
    bool operator< (const Op& r) const
    {
        return t > r.t;
    }
};
priority_queue<Op> heap;

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

void eval()
{
    auto t = heap.top();
    heap.pop();

    auto &a = g[node[t.id]], &b = g[t.hid];
    if (b.size() > a.size() || b.size() == a.size() && b.back() < a.back())
    {
        node[t.id] = t.hid;
        for (int i = h[t.id]; ~i; i = ne[i])
            if (e[i] != t.pid && e[i] != t.id)
                heap.push({t.t + w, e[i], t.id, t.hid});
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    g.push_back({0});
    memset(h, -1, sizeof h);
    while (m -- )
    {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b), add(b, a);
    }

    scanf("%d%d", &w, &Q);
    getchar();
    char str[100];
    while (Q -- )
    {
        fgets(str, 100, stdin);
        stringstream ssin(str);
        int a[3], cnt = 0;
        while (ssin >> a[cnt]) cnt ++ ;
        if (cnt == 3)
        {
            while (heap.size() && heap.top().t <= a[1]) eval();
            g.push_back(g[node[a[0]]]);
            g.back().push_back(a[2]);
            node[a[0]] = g.size() - 1;
            for (int i = h[a[0]]; ~i; i = ne[i])
                if (e[i] != a[0])
                    heap.push({a[1] + w, e[i], a[0], node[a[0]]});
        }
        else
        {
            while (heap.size() && heap.top().t <= a[1]) eval();
            printf("%d ", g[node[a[0]]].size());
            for (auto x: g[node[a[0]]])
                printf("%d ", x);
            puts("");
        }
    }
    return 0;
}

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

  1. 魔数
    ccf-csp 2019冬季真题题解_第16张图片
    ccf-csp 2019冬季真题题解_第17张图片
    ccf-csp 2019冬季真题题解_第18张图片

代码:

#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef __int128 I128;
typedef unsigned long long ULL;
const int N = 1000010, M = 33;
const ULL MOD = 2009731336725594113ull;

int n, m;
unordered_map<ULL, int> v2id;
ULL id2v[M], prod[N][M];
int g[M][M], id;
ULL U[] = {
    314882150829468584ull,
    427197303358170108ull,
    1022292690726729920ull,
    1698479428772363217ull,
    2006101093849356424ull,
};

struct Node
{
    int l, r, k;
    int s[M];
}tr[N << 2];

void init()
{
    queue<ULL> q;
    q.push(1);
    v2id[1] = ++ id;
    id2v[id] = 1;
    while (q.size())
    {
        auto t = q.front();
        q.pop();
        for (int i = 0; i < 5; i ++ )
        {
            auto r = (I128)t * U[i] % MOD;
            if (!v2id.count(r))
            {
                v2id[r] = ++ id;
                id2v[id] = r;
                q.push(r);
            }
        }
    }
    for (int i = 1; i <= id; i ++ )
        for (int j = 1; j <= id; j ++ )
            g[i][j] = v2id[(I128)id2v[i] * id2v[j] % MOD];
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= id; j ++ )
            prod[i][j] = (prod[i - 1][j] + id2v[j]) % MOD;
}

void pushup(int u)
{
    auto l = tr[u << 1].s, r = tr[u << 1 | 1].s;
    for (int i = 1; i <= id; i ++ )
        tr[u].s[i] = l[i] + r[i];
}

void eval(int u, int k)
{
    static int tmp[M];
    for (int i = 1; i <= id; i ++ ) tmp[i] = tr[u].s[g[i][k]];
    for (int i = 1; i <= id; i ++ ) tr[u].s[i] = tmp[i];
    if (tr[u].k) tr[u].k = g[tr[u].k][k];
    else tr[u].k = k;
}

void pushdown(int u)
{
    int k = tr[u].k;
    if (k)
    {
        eval(u << 1, k), eval(u << 1 | 1, k);
        tr[u].k = 0;
    }
}

void build(int u, int l, int r)
{
    tr[u] = {l, r};
    if (l == r)
    {
        for (int i = 1; i <= id; i ++ )
            tr[u].s[i] = prod[l][i] % 2019;
        return;
    }
    int mid = l + r >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
    pushup(u);
}

void update(int u, int l, int r, int k)
{
    if (tr[u].l >= l && tr[u].r <= r) eval(u, k);
    else
    {
        pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if (l <= mid) update(u << 1, l, r, k);
        if (r > mid) update(u << 1 | 1, l, r, k);
        pushup(u);
    }
}

int query(int u, int l, int r)
{
    if (tr[u].l >= l && tr[u].r <= r) return tr[u].s[1];
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1, res = 0;
    if (l <= mid) res = query(u << 1, l, r);
    if (r > mid) res += query(u << 1 | 1, l, r);
    return res;
}

int main()
{
    scanf("%d%d", &n, &m);
    init();
    build(1, 1, n);

    while (m -- )
    {
        int l, r;
        scanf("%d%d", &l, &r);
        int t = query(1, l, r);
        printf("%d\n", t);
        update(1, l, r, t % 5 + 2);
    }

    return 0;
}

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

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

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