Contest3924 - 计科23级算法设计与分析平时作业-03

题目链接

A.Knight Moves

题面

思路

马的bfs、最短路径问题。模板题

示例代码

#include<bits/stdc++.h>

using namespace std;

#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'

const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;

struct point{
    int x, y;
    point(int x, int y) : x(x), y(y) {}
};

int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};

void dfs(string start, string end) {
    if(start == end) {
        cout << "To get from " << start << " to " << end << " takes " << 0 << " knight moves.\n";
        return;
    }
    queue<point> q;
    point start_point(start[0] - 'a', start[1] - '1'), end_point(end[0] - 'a', end[1] - '1');
    q.push(start_point);
    vector<vector<bool>> vis(8, vector<bool>(8, false));
    vis[start_point.x][start_point.y] = true;
    vector<vector<int>> dist(8, vector<int>(8, inf));
    dist[start_point.x][start_point.y] = 0;

    while(!q.empty()) {
        point curr = q.front();
        q.pop();
        if(curr.x == end_point.x && curr.y == end_point.y) {
            cout << "To get from " << start << " to " << end << " takes " << dist[curr.x][curr.y] << " knight moves.\n";
            return;
        }
        fer(i, 0, 8){
            int nx = curr.x + dx[i], ny = curr.y + dy[i];
            auto OnRange = [] (int a, int b) {return a >= 0 && a < 8 && b >= 0 && b < 8;};
            if(OnRange(nx, ny) && !vis[nx][ny]) {
                if(dist[curr.x][curr.y] + 1 < dist[nx][ny]) {
                    dist[nx][ny] = dist[curr.x][curr.y] + 1;
                    q.push({nx, ny});
                    vis[nx][ny] = true;
                }
            }
        }
    }

}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);

    string s1, s2;
    while(cin >> s1 >> s2) {
        dfs(s1, s2);
    }

    return 0;
}

B.Gold Transportation

题面

示例代码

#include <bits/stdc++.h>

using namespace std;

#define ll long long
// #define int ll
#define pii pair<int, int>
#define all(x) x.begin(), x.end()
#define fer(i, m, n) for (int i = m; i < n; ++i)
#define ferd(i, m, n) for (int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'

const int inf = 0x3f3f3f3f;
const int N = 1001, M = 100001;

int head[N], nex[M], to[M], val[M], now;
void add(int a, int b, int v)
{
    to[++now] = b;
    val[now] = v;
    nex[now] = head[a];
    head[a] = now;
    to[++now] = a;
    val[now] = 0;
    nex[now] = head[b];
    head[b] = now;
}

//*********************

int sp, ep, d[N];

int bfs()
{
    queue<int> Q;
    memset(d, -1, sizeof(d));
    d[sp] = 0;
    Q.push(sp);
    while (!Q.empty())
    {
        int p = Q.front();
        Q.pop();
        for (int i = head[p]; ~i; i = nex[i])
        {
            int u = to[i];
            if (d[u] == -1 && val[i] > 0)
            {
                d[u] = d[p] + 1;
                Q.push(u);
            }
        }
    }
    return d[ep] != -1;
}

int dfs(int p, int v)
{
    int r = 0;
    if (p == ep)
        return v;
    for (int i = head[p]; (~i) && r < v; i = nex[i])
    {
        int u = to[i];
        if (val[i] > 0 && d[u] == d[p] + 1)
        {
            int x = dfs(u, min(val[i], v - r));
            r += x;
            val[i] -= x;
            val[i ^ 1] += x;
        }
    }
    if (!r)
        d[p] = -2;
    return r;
}

int dinic()
{
    int ans = 0, t;
    while (bfs())
    {
        while (t = dfs(sp, inf))
            ans += t;
    }
    return ans;
}

//***********************

void init()
{
    now = -1; // 要求第一条边为0
    memset(head, -1, sizeof(head));
}

int n, m, sum;
int a[M], b[M], v[M];
int s[N], g[N];

int judge(int limit)
{
    init();
    sp = 0, ep = 201;
    for (int i = 1; i <= m; i++)
    {
        if (v[i] <= limit)
        {
            add(a[i], b[i], inf);
            add(b[i], a[i], inf);
        }
    }
    for (int i = 1; i <= n; i++)
    {
        if (s[i])
        {
            add(0, i, s[i]);
        }
        if (g[i])
        {
            add(i, 201, g[i]);
        }
    }
    int ans = dinic();
    if (ans == sum)
        return 1;
    return 0;
}

int main()
{
    while (scanf("%d", &n) != EOF)
    {
        if (!n)
            break;
        sum = 0;
        for (int i = 1; i <= n; i++)
            scanf("%d", s + i), sum += s[i];
        for (int i = 1; i <= n; i++)
            scanf("%d", g + i);

        scanf("%d", &m);
        int l = 0, r = 1e4;
        for (int i = 1; i <= m; i++)
            scanf("%d%d%d", a + i, b + i, v + i);
        if (!judge(1e4))
        {
            printf("No Solution\n");
            continue;
        }
        if (judge(0))
        {
            printf("%d\n", 0);
            continue;
        }
        while (r - l > 1)
        {
            int mid = l + r >> 1;
            if (judge(mid))
                r = mid;
            else
                l = mid;
        }
        printf("%d\n", r);
    }
}

C.Function Run Fun

题面

思路

记忆化搜索

示例代码

#include<bits/stdc++.h>

using namespace std;

#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'

const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;

ll memo[100][100][100];

ll w(int a, int b, int c) {
    if(a <= 0 || b <= 0 || c <= 0) return 1;
    if(memo[a][b][c] != -1) return memo[a][b][c];
    if(a > 20 || b > 20 || c > 20)
        a = b = c = 20, memo[a][b][c] = w(20, 20, 20);
    else if(a < b && b < c) 
        memo[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c);
    else memo[a][b][c] = w(a - 1, b, c) + w(a - 1, b - 1, c) + w(a - 1, b, c - 1) - w(a - 1, b - 1, c - 1);
    return memo[a][b][c];
}

signed main() {
    //ios::sync_with_stdio(false); cin.tie(nullptr);

    int a, b, c;
    memset(memo, -1, sizeof(memo));
    while(cin >> a >> b >> c) {
        if(a == -1 && b == -1 && c == -1) break;
        printf("w(%d, %d, %d) = %lld\n", a, b, c, w(a, b, c));
    }
    return 0;
}

D.Equation Solver

题面

示例代码

#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;

const double EPS = 1e-8;

pair<double, double> parse_expression(const string& s, int& pos);
pair<double, double> parse_term(const string& s, int& pos);
pair<double, double> parse_factor(const string& s, int& pos);

int parse_number(const string& s, int& pos) {
    int num = 0;
    while (pos < s.size() && isdigit(s[pos])) {
        num = num * 10 + (s[pos] - '0');
        pos++;
    }
    return num;
}

pair<double, double> parse_factor(const string& s, int& pos) {
    if (s[pos] == 'x') {
        pos++;
        return {1.0, 0.0};
    } else if (isdigit(s[pos])) {
        int num = parse_number(s, pos);
        return {0.0, (double)num};
    } else if (s[pos] == '(') {
        pos++;
        auto res = parse_expression(s, pos);
        if (pos < s.size() && s[pos] == ')') {
            pos++;
        }
        return res;
    } else {
        return {0.0, 0.0};
    }
}

pair<double, double> parse_term(const string& s, int& pos) {
    auto res = parse_factor(s, pos);
    double a = res.first, b = res.second;
    while (pos < s.size() && s[pos] == '*') {
        pos++;
        auto factor = parse_factor(s, pos);
        double new_a = a * factor.second + b * factor.first;
        double new_b = b * factor.second;
        a = new_a;
        b = new_b;
    }
    return {a, b};
}

pair<double, double> parse_expression(const string& s, int& pos) {
    pair<double, double> res = {0.0, 0.0};
    bool positive = true;
    if (pos < s.size() && (s[pos] == '+' || s[pos] == '-')) {
        positive = (s[pos] == '+');
        pos++;
    }
    auto term = parse_term(s, pos);
    if (!positive) {
        term.first *= -1;
        term.second *= -1;
    }
    res.first = term.first;
    res.second = term.second;

    while (pos < s.size() && (s[pos] == '+' || s[pos] == '-')) {
        char op = s[pos];
        pos++;
        auto term = parse_term(s, pos);
        if (op == '+') {
            res.first += term.first;
            res.second += term.second;
        } else {
            res.first -= term.first;
            res.second -= term.second;
        }
    }
    return res;
}

int main() {
    string line;
    int case_num = 1;
    while (getline(cin, line)) {
        int eq_pos = line.find('=');
        string left_str = line.substr(0, eq_pos);
        string right_str = line.substr(eq_pos + 1);

        int pos = 0;
        auto left = parse_expression(left_str, pos);
        pos = 0;
        auto right = parse_expression(right_str, pos);

        double total_a = left.first - right.first;
        double total_b = right.second - left.second;

        cout << "Equation #" << case_num << endl;
        if (fabs(total_a) < EPS) {
            if (fabs(total_b) < EPS) {
                cout << "Infinitely many solutions." << endl;
            } else {
                cout << "No solution." << endl;
            }
        } else {
            double x = total_b / total_a;
            if(abs(x) <1e-9) x = abs(x);
            cout << "x = " << fixed << setprecision(6) << x << endl;
        }
        cout << endl;
        case_num++;
    }
    return 0;
}

E.Triangular Sums

题面

思路

加权求和,直接模拟即可

示例代码

#include<bits/stdc++.h>

using namespace std;

#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'

const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);

    int t;
    cin >> t;
    fer(i, 1, t + 1) {
        int n;
        cin >> n;
        ll ans = 0;
        fer(k, 1, n + 1) ans += k * (1 + k + 1) * (k + 1) / 2;
        cout << i << ' ' << n << ' ' << ans << '\n';
    }

    return 0;
}

F.W‘s Cipher

题面

思路

将字符串字符分成三组,将每组进行循环移位,注意处理空组串的情况

示例代码

#include<bits/stdc++.h>

using namespace std;

#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'

const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;

void fun(string &s, int k) {
    k %= s.size();
    if(k < 0) k += s.size();
    s = s.substr(s.size() - k) + s.substr(0, s.size() - k);
}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);

    int k1, k2, k3;
    while(cin >> k1 >> k2 >> k3, k1 || k2 || k3) {
        string s;
        cin >> s;
        vector<int> table(s.size());
        string s1, s2, s3;
        fer(i, 0, s.size()) {
            if(s[i] >= 'a' && s[i] <= 'i') table[i] = 1, s1 += s[i];
            else if(s[i] >= 'j' && s[i] <= 'r') table[i] = 2, s2 += s[i];
            else table[i] = 3, s3 += s[i];
        }
        if(s1.size()) fun(s1, k1);
        if(s2.size()) fun(s2, k2);
        if(s3.size()) fun(s3, k3);
        string ans;
        int ind1 = 0, ind2 = 0, ind3 = 0;
        fer(i, 0, s.size()) {
            if(table[i] == 1) ans += s1[ind1++];
            else if(table[i] == 2) ans += s2[ind2++];
            else ans += s3[ind3++];
        }
        cout << ans << '\n';
    }

    return 0;
}
posted @ 2025-03-25 09:34  Thin_time  阅读(28)  评论(0)    收藏  举报