第十三届西南民族大学程序设计竞赛题解

A. 落花》&&《红衣集》

模拟

#include
#define int long long
using namespace std;
 
signed main()
{
    int n;
    cin >> n;
    vector<int> a(n - 1), b(n - 1);
    for (int i = 0; i < n - 1; i++) cin >> a[i];
    for (int i = 0; i < n - 1; i++) cin >> b[i];
    int ans = a[0], res = b[0];
    for (int i = 1; i < n - 1; i++)
    {
        if (res >= b[i]) continue;
        if (i == n - 2) ans += a[i];
        else
        {
            if (b[i] == b[i + 1]) ans += min(a[i], a[i + 1]);
            else
            {
                if (b[i] > b[i + 1]) ans += a[i];
                else ans += a[i + 1];
            }
            res = max(b[i], b[i + 1]);
            i++;
        }
    }
    cout << ans << '\n';
    return 0;
}

B. 留春春不住,春归人寂寞。

最短路板子题,注意是无向图

#include
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 1000010 ;
int e[N], ne[N], w[N], h[N], idx;
int st[N], dist[N];
int n, m ;
void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
void dijkstra()
{
    for (int i = 1; i <= n; i++) dist[i] = 1e18;
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    dist[1] = 0;
    heap.push({0ll, 1});
    while (heap.size())
    {
        auto t = heap.top();
        heap.pop();
        int ver = t.second;
        if (st[ver]) continue;
        st[ver] = 1;
        for (int i = h[ver]; i != -1; i = ne[i]) {
            int j = e[i];
            if (dist[j] > dist[ver] + w[i]) {
                dist[j] = dist[ver] + w[i];
                heap.push({dist[j], j});
            }
        }
    }
}
signed main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    memset(h, -1, sizeof h);
    cin >> n >> m ;
    while (m--)
    {
        int a, b, c ;
        cin >> a >> b >> c;
        add(a, b, c);
        add(b, a, c);
    }
    dijkstra();
    int t;
    cin >> t;
    while (t--)
    {
        int x;
        cin >> x;
        cout << dist[x] << '\n';
    }
    return 0;
}

C. 厌风风不定,风起花萧索。

多重前缀和,一个字符串一个前缀和

#include
#define int long long
using namespace std;
unordered_map<string, int> mp;
const int N = 1010;
int a[1010][1010];
int n, x, num = 1;
string s;

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> s >> x;
        if (!mp[s]) mp[s] = num++;
        a[mp[s]][i] = x;
    }
    for (int i = 1; i < num; i++)
    {
        for (int j = 1; j <= n; j++)
            a[i][j] += a[i][j - 1];
    }
    int t;
    cin >> t;
    while (t--)
    {
        int l, r;
        string s;
        cin >> l >> r >> s;
        if (!mp[s]) cout << 0 << '\n';
        else 
        {
            int k = mp[s];
            cout << a[k][r] - a[k][l - 1] << '\n';
        }
    }
    return 0;
}

D. 既兴风前叹,重命花下酌。

第一题蒙的

第二题是一个数学猜想

第三题玩游戏都知道

第四题是平面几何的常用操作

第五题看你C语言学得好不好了

第六题一眼真,给你一个模拟操作,傻子才真去模拟,基本不会错

第七题略

#include
using namespace std;
 
int main()
{
    cout << "FTFTTTF" << '\n';
    return 0;
}

E. 劝君尝绿醅,教人拾红萼。

字符串输出,注意转义字符

#include
using namespace std;

int main()
{
    cout << "\"xi\\nan\\min\\zu\\da\\xue,zhen\\mei!\"";
    return 0;
}

F. 桃飘火焰焰,梨堕雪漠漠。

排序贪心

#include
using namespace std;

int main()
{
    int n, m, k;
    long long ans = 0;
    cin >> n >> m >> k;
    vector<bool> b(n + 1);
    vector<pair<int, int>> a(n);
    for (int i = 0; i < n; i++)
    {
        int x;
        cin >> x;
        a[i] = {x, i + 1};
    }
    for (int i = 0; i < m; i++)
    {
        int x;
        cin >> x;
        ans += a[x - 1].first;
        b[x] = true;
    }
    
    sort(a.begin(), a.end());
    k -= m;
    if (!k)
    {
        cout << ans << '\n';
        return 0;
    }
    for (int i = 0; i < n; i++)
    {
        if (!b[a[i].second]) 
        {
            ans += a[i].first;
            k--;
            if (!k) break;
        }
    }
    cout << ans << '\n';
    return 0;
}

G. 独有病眼花,春风吹不落。

并查集,AcWing提高课并查集第一题原题

AcWing 1250. 格子游戏 - AcWing

#include
using namespace std;
const int N = 10000010;
int p[N];

int find(int x)
{
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}

int main()
{
    int n, m;
    cin >> n >> m;
    int flag = 1;
    for (int i = 0; i < N; i++) p[i] = i;
    for (int i = 1; i <= m; i++)
    {
        int a, b, c, d;
        char op[2];
        cin >> a >> b >> op;
        if (*op == 'D') c = a + 1, d = b;
        else c = a, d = b + 1;
        int A = (a - 1) * n + b;
        int B = (c - 1) * n + d;
        int pa = find(A);
        int pb = find(B);
        if (pa == pb)
        {
            cout << i << '\n';
            flag = 0;
            break;
        }
        else 
        {
            p[pa] = pb;
        }
    }
    if (flag) cout << "draw" << '\n';
    return 0;
}

H. 荷池堪作镜,盈盈可鉴心。

简单递推,注意取模

#include
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
int a[10000010];
int main()
{
    int x;
    cin >> x;
    a[0] = 0, a[1] = 1, a[2] = 2, a[3] = 3;
    for (int i = 4; i <= x; i++)
    {
        a[i] = (a[i - 1] + a[i - 3]) % mod;
    }
    cout << a[x] << '\n';
    return 0;
}

I. 荷香堪筑梦,鸳鸯和月寻。

搜索,建议bfs,容错率大

#include
using namespace std;

const int N = 1010;
char g[N][N];
bool st[N][N];
int n, m, a;

void bfs(int x, int y)
{
    queue<pair<int, int>> q;
    q.push({x, y});
    st[x][y] = true;
    while (q.size())
    {
        auto t = q.front();
        q.pop();
        int x = t.first, y = t.second;
        for (int i = y; i <= min(y + a, m - 1); i++)
        {
            if (st[x - 1][i] || g[x - 1][i] == '*') continue;
            st[x - 1][i] = true;
            q.push({x - 1, i});
            if (x == 0)
            {
                cout << "yes" << '\n';
                return;
            }
        }
        for (int i = y - 1; i >= max(y - a, 0); i--)
        {
            if (st[x - 1][i] || g[x - 1][i] == '*') continue;
            st[x - 1][i] = true;
            q.push({x - 1, i});
            if (x == 0)
            {
                cout << "yes" << '\n';
                return;
            }
        }
    }
    cout << "no" << '\n';
    return;
}

int main()
{
    cin >> n >> m >> a;
    for (int i = 0; i < n; i++) cin >> g[i];
    for (int i = 0; i < m; i++)
    {
        if (g[n - 1][i] == 'a')
        {
            bfs(n - 1, i);
            break;
        }
    }
    return 0;
}

J. 荷香莫深湎,终付秋风落。

简单字符串

#include
using namespace std;
 
int main()
{
    string s;
    int ans = 0;
    while (getline(cin, s))
    {
        for (int i = 1; i < s.size(); i++)
            if (s[i - 1] == ':' && s[i] == 'w') ans++;
    }
    cout << ans << '\n';
    return 0;
}

K. 荷香竟深湎,永待盛夏陌。

暴力枚举

#include
using namespace std;

void solve()
{
    vector<int> a(5), b(5);
        for (int i = 1; i <= 4; i++) cin >> a[i];
        for (int i = 0; i < 4; i++) // 1
            for (int j = 0; j < 4; j++) // 2
                for (int x = 0; x < 4; x++) // 3
                    for (int y = 0; y < 4; y++) // 4
                    {
                        b[1] = a[1] + i + j + y;
                        b[2] = a[2] + i + j + x;
                        b[3] = a[3] + j + x + y;
                        b[4] = a[4] + i + x + y;
                        for (int c = 1; c <= 4; c++)
                        {
                            b[c] %= 4;
                            if (!b[c]) b[c] = 4;
                        }
                        if (b[1] == b[2] && b[2] == b[3] && b[3] == b[4])
                        {
                            cout << i + j + x + y << '\n';
                            while (i--) cout << 1 << " ";
                            while (j--) cout << 2 << " ";
                            while (x--) cout << 3 << " ";
                            while (y--) cout << 4 << " ";
                            cout << '\n';
                            return;
                        }
                    }
}

int main()
{
    int t;
    cin >> t;
    while (t--) solve();
    return 0;
}

L. 相思子肯来,约在莲花岸。

模拟

#include
using namespace std;

struct node
{
    int x, y, k;
};

int main()
{
    int n, m;
    cin >> n >> m;
    vector<node> a(n), b(m);
    for (int i = 0; i < n; i++) cin >> a[i].x >> a[i].y >> a[i].k;
    for (int i = 0; i < m; i++) cin >> b[i].x >> b[i].y >> b[i].k;
    for (int i = 0; i < n; i++)
    {
        int minn = 10000, A;
        int maxx = 0, B;
        for (int j = 0; j < m; j++)
        {
            int dx = a[i].x - b[j].x;
            int dy = a[i].y - b[j].y;
            int d = dx * dx + dy * dy;
            if (d < minn) 
            {
                minn = d;
                A = j + 1;
            }
            if (d > maxx)
            {
                maxx = d;
                B = j + 1;
            }
        }
        if (a[i].k) cout << B << " ";
        else cout << A << " ";
    }
    cout << '\n';
    for (int i = 0; i < m; i++)
    {
        int minn = 10000, A;
        int maxx = 0, B;
        for (int j = 0; j < n; j++)
        {
            int dx = a[j].x - b[i].x;
            int dy = a[j].y - b[i].y;
            int d = dx * dx + dy * dy;
            if (d < minn) 
            {
                minn = d;
                A = j + 1;
            }
            if (d > maxx)
            {
                maxx = d;
                B = j + 1;
            }
        }
        if (b[i].k) cout << B << " ";
        else cout << A << " ";
    }
    return 0;
}

M. 潇潇日暮时,掠水鸳鸯散。

01背包

#include
#define int long long
using namespace std;

signed main()
{
    int n, m;
    cin >> n >> m;
    vector<int> f(n + 1);
    for (int i = 0; i < m; i++)
    {
        int v, w;
        cin >> v >> w;
        for (int j = n; j >= v; j--)
        {
            f[j] = max(f[j], f[j - v] + w);
        }
    }
    cout << f[n] << '\n';
    return 0;
}

你可能感兴趣的:(学习总结,算法)