ICode9

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

2022杭电多校补题1

2022-07-27 16:37:53  阅读:140  来源: 互联网

标签:杭电多校 fr int cin long -- 补题 2022 define



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

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

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

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

ICode9版权所有