Report problem-solving small Z series

In the valley you have stumbled upon a series of brush such questions, probably \ (15 \) path around the subject.

And konjac found that the topic is basically the whole human family is LittleZbig brotherOrzOrz

So whim, want this series all written, then there will be some paper.


\ (Ps: \) by Tacca do question their own order, not necessarily representative of difficulty.

\ (1 \) small Z matrix

Characteristic function because the topics given \ (G (A) \) is \ (2 \) results modulo, so it is easy to find the contribution of all elements except the diagonal answers are \ ( 0 \) , so the first step single contribution to the cumulative diagonal.

Then we found that each flip a row one had no effect on the answer, that is, just flip the desires and \ ((\) in \ (mod \ 2 \) under conditions \ () \) , so every flip direct access to an exclusive OR It can be.

code:

#include <iostream>
#include <cstdio>
#include <cstring>

int n, q, g, x;

int main() {
    scanf("%d%d", &n, &q);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &x);
            if (i == j) g = (g + x) % 2; 
        }
    }
    for (int i = 1; i <= q; i++) {
        scanf("%d", &x);
        if (x == 3) printf("%d", g);
        else {
            scanf("%d", &x);
            g ^= 1;
        }
    }
    return 0;
}

\ (2 \) small number Z k of compact

Recently learned digit \ (DP \) saw this question \ (...... \)And almost exactly the same number and windy

Specific treatment methods and \ (windy \) number is basically the same, do not understand the digital \ (DP \) can see konjac finishing study notes , containing \ (windy \) detailed the number of problem solution.

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
#define abs(a) ((a) < 0 ? -(a) : (a))

int f[25][15], num[25], a, b, opt;

void init() {
    for (int i = 0; i <= 9; i++) f[1][i] = 1;
    for (int i = 2; i <= 20; i++) {
        for (int j = 0; j <= 9; j++) {
            for (int k = 0; k <= 9; k++)
                if (abs(j - k) <= opt) f[i][j] += f[i - 1][k];
        }
    }
}

int calc(int x) {
    int len = 0, ans = 0;
    memset(num, 0, sizeof(num));
    while (x) {
        num[++len] = x % 10;
        x /= 10;
    }
    for (int i = 1; i <= len - 1; i++) {
        for (int j = 1; j <= 9; j++)
            ans += f[i][j];
    }
    for (int i = len; i >= 1; i--) {
        for (int j = 0; j < num[i]; j++) {
            if (i == len && !j) continue;
            if (abs(num[i + 1] - j) <= opt || i == len) ans += f[i][j];
        }
        if (abs(num[i + 1] - num[i]) > opt && i != len) break;
    }
    return ans;
}

signed main() {
    scanf("%lld%lld%lld", &a, &b, &opt);
    init();
    printf("%lld\n", calc(b + 1) - calc(a));
    return 0;
}

\ (3 \) small Z carriages

According to the meaning of problems, we need only look at statistics at the same time on the train up to how many people you can, and then if the number \ (mod \ 36 \) is zero, the number of direct output \ (/ 36 \) , otherwise the \ (1 + \) .

But we must note that the title of this track is circular, so it will happen:

\[4->3\]

Line should be:

\[4->1->2->3\]

Then we think about how we should deal with this situation.

In this case seems to be equivalent to: Think for a moment we find \ (4 \) got the number, and then in the \ (1 \) No. cars, so every time we encounter \ (x> y \) when the situation directly at the first points accumulate once.

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#define max(a, b) ((a) > (b) ? (a) : (b))

const int maxn = 1e6 + 6;
int on[maxn], off[maxn], n, m, x, y, z;

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i++) {
        scanf("%d%d%d", &x, &y, &z);
        on[x] += z;
        off[y] += z;
        if (x > y)
            on[1] += z;
    }
    int ans = 0, sum = 0;
    for (int i = 1; i <= n; i++) {
        sum += on[i];
        sum -= off[i];
        ans = max(ans, sum);
    }
    if (ans % 36 == 0)
        std::cout << ans / 36 << '\n';
    else std::cout << ans / 36 + 1 << '\n';
    return 0;
}

\ (4 \) small love letter Z

Good a simulation title \ (...... \)

We can see from the examples above, goes on transparent paper is rotated clockwise, and then write down each time point will find it is a regular flip:

\[(i,j)\Rightarrow (j,n-i+1)\]

So every time we can see the current accumulated to answer, and then press the laws of the coordinates transformation, three times just fine mess.

Suddenly thought, flipping point clockwise on the law and seemingly mathematical Cartesian coordinate system \ (90 \) similar law degree \ (...... \)

code:

#include <iostream>
#include <cstdio>
#include <cstring>

using std::string;
int n;
string ans;
char s[1007][1007], ch;
bool p[1007][1007], q[1007][1007];

void reverse() {
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            q[i][j] = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (p[i][j] == 1) q[j][n - i + 1] = 1;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            p[i][j] = q[i][j];
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) {
            std::cin >> ch;
            if (ch == 'O') p[i][j] = 1;
    }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            std::cin >> s[i][j];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (p[i][j]) ans += s[i][j];
    reverse();
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (p[i][j]) ans += s[i][j];
    reverse();
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (p[i][j]) ans += s[i][j];
    reverse();
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (p[i][j]) ans += s[i][j];
    std::cout << ans << '\n';
    return 0;
}

\ (5 \) small notes Z

Design Status: Order \ (f [i] \) represents the former \ (I \) th position to a legal state minimum number you want to delete.

Plain \ (DP \) transfer equation:

\ [F [i] = min \ {f [j] j + i-1 \} j \ epsilon [a, z] \]

Means that when \ (i \) and \ (j \) when you can adjacent to the \ (i \ sim j \) to delete all the letters all.

Then it is clear that this transfer is \ (O (n ^ 2) \) , so we consider how to optimize.

We first about \ (i \) is part of all proposed, the equation becomes:

\ [F [i] = min \ {F [j] j \} + i-1 \]

At the same time, we found that only \ (26 \) letters, each letter so we maintain an array \ (G [i] \) , said:

\ [G [j] = min \ {F [j] j \} \]

Although there are two cycles, but only the second layer \ (26 \) , so the total time complexity is \ (O (26n) \) .

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>

using std::map;
using std::string;
const int maxn = 1e5 + 5;
bool vis[55][55];
int f[maxn], n, m, g[maxn];
string x;
char s[100005];

int main() {
    scanf("%d", &n);
    scanf("%s", s + 1);
    scanf("%d", &m);
    for (int i = 1; i <= m; i++) {
        std::cin >> x;
        vis[x[0] - 'a'][x[1] - 'a'] = vis[x[1] - 'a'][x[0] - 'a'] = true;
    }
    memset(f, 0x3f, sizeof(f));
    f[1] = 0;
    g[s[1] - 'a'] = 0 - 1;
    for (int i = 2; i <= n; i++) {
        for (int j = 0; j < 26; j++) {
            if (vis[s[i] - 'a'][j]) continue;
            f[i] = std::min(f[i], g[j] + i - 1);
        }
        g[s[i] - 'a'] = std::min(g[s[i] - 'a'], f[i] - i);
    }
    printf("%d\n", f[n]);
    return 0;
}

//f[i] = min{f[j] - j} + i - 1;

\ (6 \) small stack function Z

A \ (...... \) nausea simulationindustryTitle \ (...... \)

Thinking nothing can be said, in accordance with the subject said analog can be, you can choose \ (STL \) is \ (Stack \) , you can also choose the same handwriting as konjac a stack.

But \ (...... \) must pay attention to the details! ! ! We must pay attention to the details! ! ! We must pay attention to the details! ! !

The need to determine a short list:

  • The number of elements is not required to operate within the stack

  • Absolute value greater than the middle appears \ (1E9 \) number

  • In addition to determining when the mold or whether the divisor \ (0 \)

Then basically did not have anything, but it was disgusting \ (...... \)

No encapsulation and ugly code ......

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
#define abs(a) ((a) < 0 ? -(a) : (a))

using std::string;
string opt;
int st[100050], top, n, m, fr;

struct Node {
    string x;
    int num;
}a[2005];

signed main() {
    while (1) {
        ++n;
        std::cin >> a[n].x;
        if (a[n].x == "END") break;
        if (a[n].x == "NUM") scanf("%d", &a[n].num);
    }
    scanf("%d", &m);
    bool flag = false;
    for (int j = 1; j <= m; j++) {
        top = 0; flag = false;
        scanf("%d", &fr);
        if (fr > 1000000000) {puts("ERROR"); continue;}
        st[++top] = fr;
        for (int i = 1; i <= n; i++) {
            if (a[i].x == "NUM") {
                if (a[i].num > 1000000000) {flag = true; break;}
                st[++top] = a[i].num;
            }
            else if (a[i].x == "POP") {
                if (top == 0) {flag = true; break;}
                else top--;
            }
            else if (a[i].x == "INV") 
                if (top == 0) {flag = true; break;}
                else {int temp = st[top--]; st[++top] = -temp;}
            else if (a[i].x == "DUP") 
                if (top == 0) {flag = true; break;}
                else {int temp = st[top]; st[++top] = temp;}
            else if (a[i].x == "SWP") 
                if (top < 2) {flag = true; break;}
                else std::swap(st[top], st[top - 1]);
            else if (a[i].x == "ADD") 
                if (top < 2) {flag = true; break;}
                else {
                    int temp1 = st[top--], temp2 = st[top--];
                    if (abs(temp1 + temp2) > 1000000000) {flag = true; break;}
                    st[++top] = temp1 + temp2;
                }
            else if (a[i].x == "SUB") 
                if (top < 2) {flag = true; break;}
                else {
                    int temp1 = st[top--], temp2 = st[top--];
                    if (abs(temp2 - temp1) > 1000000000) {flag = true; break;}
                    st[++top] = temp2 - temp1;
                }
            else if (a[i].x == "MUL") 
                if (top < 2) {flag = true; break;}
                else {
                    int temp1 = st[top--], temp2 = st[top--];
                    if (abs(temp1 * temp2) > 1000000000) {flag = true; break;}
                    st[++top] = temp1 * temp2;
                }
            else if (a[i].x == "DIV") 
                if (top < 2) {flag = true; break;}
                else {
                    int temp1 = st[top--], temp2 = st[top--];
                    if (temp1 == 0) {flag = true; break;}
                    if (abs(temp2 / temp1) > 1000000000) {flag = true; break;}
                    st[++top] = temp2 / temp1;
                }
            else if (a[i].x == "MOD") 
                if (top < 2) {flag = true; break;}
                else {
                    int temp1 = st[top--], temp2 = st[top--];
                    if (temp1 == 0) {flag = true; break;}
                    if (abs(temp2 % temp1) > 1000000000) {flag = true; break;}
                    st[++top] = temp2 % temp1;
                }
        }
        if (flag || top != 1) puts("ERROR");
        else std::cout << st[top] << '\n';
    }
    return 0;
}

\ (7 \) small Z of AK program

Analysis of Algorithmslabel\ (: \) Binary heapPriority Queue

This question is this first thought Tacca is greedy, the product of a point to coordinate with the title number of keywords, but the idea is very easy to \ (hack \) , but this is no way to consider the situation to go back.

Then came a breakthrough at this question, questions surface in this sentence \ (: \)当然,也可以过机房而不入 , then down the sentence, we consider, can go all the way, does not consider looking back, only to take into account not enter a room.

Then we use a large root heapPriority QueueWhich is recorded into the room, each entering a new room, we had room to count all the consumption of total time so far, and then added to the current point coordinates, if \ (> m \) continues to subtract the first team at the same time the number of rooms \ (- \) , when the operation is finished answer to update.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define int long long
#define max(a, b) ((a) > (b) ? (a) : (b))

std::priority_queue<int>q;
const int maxn = 1e5 + 5;
int n, m, tot, sum, ans;

struct Node {
    int x, t;
    bool operator < (const Node &rhs) const {
        return x < rhs.x;
    }
}a[maxn];

template<class T>
inline T read(T &x) {
    x = 0; int w = 1, ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') w = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - 48; ch = getchar();}
    return x *= w;
}

signed main() {
    read(n), read(m);
    for (int i = 1; i <= n; i++)
        read(a[i].x), read(a[i].t);
    std::sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; i++) {
        if (a[i].x > m) break;
        q.push(a[i].t);
        ++tot;
        sum += a[i].t;
        while (!q.empty() && sum + a[i].x > m) {
            --tot;
            sum -= q.top();
            q.pop();
        }
        ans = max(ans, tot);
    }
    printf("%lld\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Hydrogen-Helium/p/11737950.html