ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2022杭电多校第一场部分题解

2022-07-20 17:04:13  阅读:241  来源: 互联网

标签:杭电多校 y2 return int 题解 x2 2022 y1 x1


Dragon slayer

题解:

解法1:可以二进制枚举当前存在哪些墙,然后bfs;
解法2:可以观察到只有删掉墙才会有贡献,相当于边权为1,其他情况边权为0,采用状压01bfs

代码:

#include <bits/stdc++.h>
//#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
#define SZ(v) (int) v.size()


const int N = 16;
int d[N][N][1 << 15];
struct T {
    int x1, y1, x2, y2;
} wall[N];
int n, m, k;
int sx, sy, tx, ty;
struct TT {
    int x, y, st;
};
bool vis[N][N][1 << 15];
pair<int, int> moves[] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}}; //ULRD
bool check(int nx, int ny, int x, int y, int k, int dir) {
    double x1 = wall[k].x1 , y1 = wall[k].y1 ;
    double x2 = wall[k].x2 , y2 = wall[k].y2 ;
    if (dir == 1) {
        if (x1 == x2 and nx == x1 and x == x1 - 1) {
            if (y < min(y1, y2)) return false;
            if (y >= max(y1, y2)) return false;
            return true;
        }
    } else if (dir == 2) {
        if (y1 == y2 and ny == y1 and y == ny - 1) {
            if (x < min(x1, x2)) return false;
            if (x >= max(x1, x2)) return false;
            return true;
        }
    } else if (dir == 3) {
        if (y1 == y2 and y == y1 and ny == y1 - 1) {
            if (x < min(x1, x2)) return false;
            if (x >= max(x1, x2)) return false;
            return true;
        }
    } else {
        if (x1 == x2 and x == x1 and nx == x1 - 1) {
            if (y < min(y1, y2)) return false;
            if (y >= max(y1, y2)) return false;
            return true;
        }
    }
    return false;
}
int bfs() {
    memset(d, 0x3f, sizeof d);
    memset(vis, 0, sizeof vis);
    deque<TT> q;
    q.push_front({sx, sy, (1 << k) - 1});
    d[sx][sy][(1 << k) - 1] = 0;
    while (q.size()) {
        auto t = q.front();
        q.pop_front();
        int x = t.x, y = t.y, st = t.st;
        if (vis[x][y][st]) continue;
        vis[x][y][st] = 1;
        int cnt = 0;
        for (auto ds : moves) {
            int dx = ds.first, dy = ds.second;
            int tx = dx + x, ty = dy + y;
            cnt++;
            if (tx >= 0 and tx < n and ty >= 0 and ty < m ) {
                int step = 0;
                int newst = st;
                for (int k = 0; k < 15; k++) {
                    if (st >> k & 1) {
                        if (check(x, y, tx, ty, k + 1, cnt)) {
                            step++;
                            newst -= (1LL << k);
                        }
                    }
                }
                if (step) {
                    d[tx][ty][newst] = d[x][y][st] + step;
                    q.push_back({tx, ty, newst});
                } else {
                    d[tx][ty][newst] = d[x][y][st] + step;
                    q.push_front({tx, ty, newst});
                }
            }
        }

    }
    int ans = 2e9;
    for (int i = 0; i < 1 << k; i++) {
        ans = min(ans, d[tx][ty][i]);
    }
    return ans;

}

void solve(int Case) {
    cin >> n >> m >> k;
    cin >> sx >> sy >> tx >> ty;
    for (int i = 1; i <= k; i++) {
        cin >> wall[i].x1 >> wall[i].y1 >> wall[i].x2 >> wall[i].y2;
    }
    cout << bfs() << nline;

}

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


    for (cin >> _, Case = 1; Case <= _; Case++)
        solve(Case);

    return 0;
}

Backpack

思路:

先考虑最基础的dp,\(f[i][j][k]\)表示前i个物品,异或和为j,体积为k的方案是否存在,\(f[i][j][k]=f[i-1][j][k]|f[i-1][j xor w[i]][k-v[i]]\)
然后考虑优化,因为只有01两种状态,使用bitset优化,\(f[i][j]\)表示前i个物品,异或和为j的bitset,bitset里面对应的第k个位置如果是1,
就相当于体积恰好为k的状态是1,因为k由第\(i-1\)的\(k-v[i]\)转移过来,所以把\(f[i][j xor w[i]]\)的状态左移\(v[i]\)然后跟\(f[i-1][j]\)取异或即可

代码:

#include <bits/stdc++.h>
#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
#define SZ(v) (int) v.size()

const int N = 1100;
bitset<N> f[N], g[N];
int w[N], v[N];

void solve(int Case) {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> v[i] >> w[i];
    for (int i = 0; i < N; i++) {
        f[i].reset();
        g[i].reset();
    }
    f[0][0] = 1;

    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < N; j++) {
            if ((j ^ w[i]) < N) {
                g[j] = f[j];
                auto cur = f[j ^ w[i]];
                cur <<= v[i];
                g[j] |= cur;

            }
        }
        for (int j = 0; j < N; j++) {
            f[j] = g[j];
        }
    }
    int ans = -1;
    for (int i = 0; i < N; i++) {
        if (f[i][m]) ans = max(ans, i);
    }
    cout << ans << nline;




}

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


    for (cin >> _, Case = 1; Case <= _; Case++)
        solve(Case);

    return 0;
}

标签:杭电多校,y2,return,int,题解,x2,2022,y1,x1
来源: https://www.cnblogs.com/koto-k/p/16498676.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有