其他分享
首页 > 其他分享> > 2022杭电多校补题1

2022杭电多校补题1

作者:互联网


title: 杭电多校补题
author: Sun-Wind
date: July 25, 2022

1002

img
img

思路

由于数据量较小,可以考虑二进制枚举+bfs
刚开始是可以任意走的
我们可以做一个放大的操作(*2倍),这样可以避免double的影响
不仅如此,放大以后只能向上下左右四个方向走,可以证明斜着走的情况并不存在(因为墙壁坐标放大以后都是偶数)

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int maxn = 1 << 16;
const int nx[4] = {0, 1, 0, -1};
const int ny[4] = {1, 0, -1, 0};

struct Node
{
    int x, y;
    int sta, cnt = 0;
    bool operator<(const Node &node) const
    {
        return cnt > node.cnt;
    }
};

int n, m, k;
int sx, sy, tx, ty;
bool vis[16][16][maxn];
int matrix[35][35];

int bfs()
{
    memset(vis, 0, sizeof(vis));
    priority_queue<Node> q;
    Node it;
    it.x = 2 * sx + 1;
    it.y = 2 * sy + 1;
    it.sta = 0;
    it.cnt = 0;
    q.push(it);
    while (!q.empty())
    {
        Node fr = q.top();
        q.pop();
        if (vis[(fr.x - 1) / 2][(fr.y - 1) / 2][fr.sta])
            continue;
        vis[(fr.x - 1) / 2][(fr.y - 1) / 2][fr.sta] = 1;
        if (fr.x == 2 * tx + 1 && fr.y == 2 * ty + 1)
            return fr.cnt;
        for (int i = 0; i < 4; ++i)
        {
            Node it = fr;
            int xx = fr.x + nx[i], yy = fr.y + ny[i];
            if (xx <= 0 || xx >= 2 * n || yy <= 0 || yy >= 2 * m)
                continue;
            if (matrix[xx][yy] && ((fr.sta >> matrix[xx][yy]) & 1) == 0)
            {
                it.sta |= (1 << matrix[xx][yy]);
                ++it.cnt;
            }
            it.x += 2 * nx[i];
            it.y += 2 * ny[i];
            q.push(it);
        }
    }
    return -1;
}

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        memset(matrix, 0, sizeof(matrix));
        cin >> n >> m >> k;
        cin >> sx >> sy >> tx >> ty;
        int x1, y1, x2, y2;
        for (int i = 1; i <= k; ++i)
        {
            cin >> x1 >> y1 >> x2 >> y2;
            if (x1 == x2)
            {
                for (int j = 2 * min(y1, y2); j <= 2 * max(y1, y2); ++j)
                    matrix[2 * x1][j] = i;
            }
            if (y1 == y2)
            {
                for (int j = 2 * min(x1, x2); j <= 2 * max(x1, x2); ++j)
                    matrix[j][2 * y1] = i;
            }
        }
        cout << bfs() << '\n';
    }
    return 0;
}

1003

img
img

思路

求当背包放满的时候,最大的异或和。
这道题直接暴力的话复杂度是O(n^3),可能会超时,所以考虑bitset优化
f[i][j] 表示异或值为i时,是否可以组合成背包容量为j的方案
如果为1就是可以组合
为0就是无法组合
转移方程就是 f[j] |= g[j ^ w];
在转移之前要记得先把当前体积考虑进去————g[j] = f[j] << v;
因为 j ^ w ^ w = j;
所以转移之后就是当异或值为j时并且考虑了这个物品之后的体积方案
最后从大到小遍历一遍,找到最大的满足m的i值(异或值)

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 1100;
bitset<N> f[N], g[N];
int n, m;
signed main()
{
    int T;
    cin >> T;
    while (T--)
    {
        cin >> n >> m;
        for (int i = 0; i <= 1024; i++)
            f[i].reset(), g[i].reset();
        f[0][0] = 1; 
        for (int i = 1; i <= n; i++)
        {
            int w, v;
            cin >> v >> w;
            for (int j = 0; j < 1024; j++)
            {
                g[j] = f[j] << v;
            }
            for (int j = 0; j < 1024; j++)
            {
                f[j] |= g[j ^ w];
            }
        }
        bool flag = false;
        for (int i = 1024; i >= 0; i--)
            if (f[i][m])
            {
                flag = true;
                cout << i << endl;
                break;
            }
        if (!flag)
            cout << "-1" << endl;
    }
    return 0;
}

1009

img
img

思路

暴力枚举
img

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 10;
int n, a[N], b[N], x[N], y[N];
bool ptsd(int x, int y)
{
    if (!x || !y || x + y == 0 || x == y)
        return true;
    return false;
}

bool ck(int xx, int yy)
{
    for (int i = 1; i <= n; i++)
        if (!ptsd(xx - x[i], yy - y[i]))
            return false;
    return true;
}

bool check()
{
    bool flag = true;
    for (int i = 1; i <= n; i++)
    {
        if (x[i] == x[1])
            continue;
        flag = false;
        if (ck(x[1], y[i]))
            return true;
        if (ck(x[1], y[i] + (x[i] - x[1])))
            return true;
        if (ck(x[1], y[i] - (x[i] - x[1])))
            return true;
    }
    if (!flag)
        return false;
    return true;
}
signed main()
{
    int T;
    cin >> T;
    while (T--)
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i] >> b[i];
        for (int i = 1; i <= n; i++)
            x[i] = a[i], y[i] = b[i];
        if (check())
            {
                cout << "YES" << endl;
                continue;
            }
        for (int i = 1; i <= n; i++)
            x[i] = b[i], y[i] = a[i];
        if (check())
            {
                cout << "YES" << endl;
                continue;
            }
        for (int i = 1; i <= n; i++)
            x[i] = a[i] + b[i], y[i] = a[i] - b[i];
       if (check())
            {
                cout << "YES" << endl;
                continue;
            }
        for (int i = 1; i <= n; i++)
            x[i] = a[i] - b[i], y[i] = a[i] + b[i];
            // cout << 1 << endl;
        if (check())
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

1012

img
img

思路

博弈的题一般都具有一定的规律,通过举例我们可以发现两个1 alice一定能赢
4个2 alice一定能赢,因为4个2可以转化为2个1
同样的道理,8个3 alice一定能赢,8个3可以转化为4个2

对alice来说,每一次都应该将数尽可能地平分
对bob来说,每一次他都应该把出现次数多地一堆删掉

由此我们可以知道,每个数的一半可以向下转化,最后检查0的个数即可

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e6 + 5;
int s[N];
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        for(int i = 0; i <= n; i++){
            cin >> s[i];
        }
        for(int i = n-1; i >= 0; i--){
            s[i] += s[i+1]/2;
        }
        if(s[0]) cout << "Alice" << endl;
        else cout << "Bob" << endl;
    } 
    return 0;
}

标签:杭电多校,fr,int,cin,long,--,补题,2022,define
来源: https://www.cnblogs.com/Sun-Wind/p/16525281.html