2022 杭电多校 第一场

11 篇文章 0 订阅
9 篇文章 0 订阅

1011 Random

签到

求一下期望 遇到0.5的时候求一下逆元就好了

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 1e6 + 10;
typedef long long ll;
int a[N];
const int mod = 1e9 + 7;
ll qpow(ll m, ll k, ll p) {
    ll res = 1 % p;
    while (k) {
        if (k & 1) res = res * m % p;
        m = m * m % p;
        k >>= 1;
    }
    return res;
}
ll inv(ll qwq) {
    return qpow(qwq, mod - 2, mod);
}
void solve() {

    int n; int m;
    cin >> m;
    
    cin >> n;
    
    if (m == n) cout << 0 << endl;
    else if ((m - n) & 1) {
        cout << ((m - n) * inv(2) % mod) << endl;
    }
    else {
        cout << (m - n) / 2 << endl;
    }
    

}
signed main() {

    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

1012 Alice and Bob

博弈

可以看出一开始序列有一个0的时候 Alice赢
假如序列中有2个1的时候 Alice也是赢的
再往后推可以发现 序列中有4个2的时候 Alice也是刚好赢的
再验证一个有8个3的时候 ,Alice是赢的

这个时候已经可以知道结论肯定是和 2的平方有关系的 然后在试试 一个1和两个2 发现这样也是可以的

然后从后往前循环一遍 a [ i − 1 ] + = a [ i ] / 2 a[i-1]+=a[i]/2 a[i1]+=a[i]/2
最后判断一下 a [ 0 ] > = 1 a[0]>=1 a[0]>=1 就好了

#include<bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
typedef long long ll;

const ll mod = 1e9+7;

void solve() {
    int n;
    cin >> n;
    vector<int> v(n+2);
    for (int i = 0; i <= n; i++) cin >> v[i];
    for (int j = n; j > 0; j--) v[j-1] += v[j] / 2;
    if (v[0]) cout << "Alice\n";
    else cout << "Bob\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T = 1;
    cin >> T;
    while (T--) solve();
    return 0;
}

1003 Backpack

dp

求恰好装满背包的时候 求异或值最大

这道题刚开始想了两个小时的正向来写 ,用 d p [ i ] dp[i] dp[i] 来表示背包容量能到达 i 的各种异或值
但这显然就是不太行 异或的性质和相加不太一样 必须要全部存下来亦或值

想到了dp[i]来表示异或值为i的各种体积值 虽然好像这样看又回到了原来一样的问题
但因为体积值是相加的 这里面的一层可以用 bitset 来优化

最后记得清空 加上dp的时候要用滚动数组

#include<bits/stdc++.h>
using namespace std;
//#define int long long 
#define endl '\n'
const int N = 1e3 + 50;
typedef long long ll;
int a[N];
const int mod = 1e9 + 7;

int v[N], w[N];

void solve() {

    bitset<1050> dp[5][N];//存在某个位置的重量
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> v[i] >> w[i];
    }


    //用dp[i][j]表示在第i论 异或值为j的体积的值

    for (int i = 1; i <= n; i++) {
        int p = i & 1, q = 1 ^ p;
        dp[p][w[i]][v[i]] = 1;
        for (int j = 1; j <= 1024; j++) {


            dp[p][j] |= (dp[q][j ^ w[i]] << (v[i]));

        }

        for (int j = 1; j <= 1024; j++) {
            dp[p][j] |= dp[q][j];
            dp[q][j].reset();
        }
    }



    int ans = -1;
    for (int j = 0; j < 1024; j++) {
        if (dp[n & 1][j][m]) {
            ans = j;
        }
    }


    cout << ans << endl;
}
signed main() {

    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

1002 Dragon slayer

队友敲滴 好像是二进制枚举一下再加上模拟就行啦

#include<bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
typedef long long ll;

const ll mod = 1e9+7;

vector<pair<pii, pii>> walls;

const int MX = 50;
const int walk[][2] = {0, 2, 2, 0, 0, -2, -2, 0};
const int walk_ck[][2] = {0, 1, 1, 0, 0, -1, -1, 0};

int mp[MX][MX];

bool bfs(int n, int m, int sx, int sy, int ex, int ey, int wall) {
    memset(mp, 0, sizeof(mp));
    for (int i = 0; i < walls.size(); i++) {
        if (wall & (1 << i)) {
            int xs = min(walls[i].first.first, walls[i].second.first);
            int xe = max(walls[i].first.first, walls[i].second.first);
            for (int x = xs; x <= xe; x++) {
                int ys = min(walls[i].first.second, walls[i].second.second);
                int ye = max(walls[i].first.second, walls[i].second.second);
                for (int y = ys; y <= ye; y++) {
                    mp[x][y] = -1;
                }
            }
        }
    }
    for (int i = 0; i < n; i++) mp[i][0] = mp[i][m-1] = -1;
    for (int i = 0; i < m; i++) mp[0][i] = mp[n-1][i] = -1;
    queue<pii> q;
    q.push({sx, sy});
    while (!q.empty()) {
        pii c = q.front(); q.pop();
        if (c.first == ex && c.second == ey) {
            return true;
        }
        for (int i = 0; i < 4; i++) {
            int ncx = c.first + walk_ck[i][0];
            int ncy = c.second + walk_ck[i][1];
            int cx = c.first + walk[i][0];
            int cy = c.second + walk[i][1];
            if (ncx >= 0 && ncx < n && ncy >= 0 && ncy < m && cx >= 0 && cx < n && cy >= 0 && cy < m && mp[ncx][ncy] != -1 && mp[cx][cy] == 0) {
                mp[cx][cy] = 1;
                q.push({cx, cy});
            }
        }
    }
    return false;
}

void solve() {
    int n,m, k;
    cin >> n >> m >> k;
    int sx,sy,ex,ey;
    cin >> sx >> sy >> ex >> ey;
    n *= 2; m *= 2;
    n++; m++;
    sx *= 2; sx++; sy *= 2; sy++;
    ex *= 2; ex++; ey *= 2; ey++;
    walls.clear();
    for (int i = 0; i < k; i++) {
        pair<pii, pii> w;
        cin >> w.first.first >> w.first.second >> w.second.first >> w.second.second;
        w.first.first *= 2; w.first.second *= 2;
        w.second.first *= 2; w.second.second *= 2;
        walls.push_back(w);
    }
    int ans = 15;
    for (int i = 0; i < (1 << k); i++) {
        if (bfs(n, m, sx, sy, ex, ey, i)) {
            ans = min(ans, k - __builtin_popcount(i));
        }
    }
    cout << ans  << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T = 1;
    cin >> T;
    while (T--) solve();
    return 0;
}

1009 Laser

随机过的!!!

队友说随机过啦 !脑瓜子嗡嗡的!

#include<bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
typedef long long ll;

const double eps = 1e-8;
const double PI = acos(-1.0);
int sgn(double x) {
    if (fabs(x) < eps) {
        return 0;
    }
    return (x < 0) ? -1 : 1;
}
struct Point {
    ll x, y;
    Point(ll x = 0.0, ll y = 0.0): x(x), y(y) {}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B) {
    return Vector(A.x + B.x, A.y + B.y);
}
Vector operator - (Point A, Point B) {
    return Vector(A.x - B.x, A.y - B.y);
}
Vector operator * (Vector A, double p) {
    return Vector(A.x * p, A.y * p);
}
Vector operator / (Vector A, double p) {
    return Vector(A.x / p, A.y / p);
}
bool operator < (const Point A, const Point B) {
    return A.x < B.x || (sgn(A.x - B.x) == 0 && A.y < B.y);
}
bool operator == (const Point A, const Point B) {
    return sgn(A.x - B.x) == 0 && sgn(A.y - B.y) == 0;
}
double Dot(Vector A, Vector B) {
    return A.x * B.x + A.y * B.y;
}
double Cross(Vector A, Vector B) {
    return A.x * B.y - A.y * B.x;
}
double Length(Vector A) {
    return sqrt(Dot(A, A));
}

Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
    Vector u = P - Q;
    double t = Cross(w, u) / Cross(v, w);
    return P + v * t;
}


int parallel(Point ua, Point ub,Point va, Point vb)//等于0说明向量平行
{
    return ((ua.x-ub.x)*(va.y-vb.y)-(va.x-vb.x)*(ua.y-ub.y));
}


mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

inline int suiji(const int &l,const int &r){
    return uniform_int_distribution<int>(l, r)(rng);
}

const ll mod = 1e9+7;

bool check(vector<Point> &vp, Point s, int n) {
    for (int i = 0; i < n; i++) {
        auto it = vp[i];
        if (!sgn(it.x - s.x) || !sgn(it.y - s.y)) continue;
        if (sgn(fabs(it.x - s.x) - fabs(it.y - s.y))) return false;
    }
    return true;
}

void solve() {
    int n;
    cin >> n;
    vector<Point> v(n);
    bool flag = true;
    for (int i = 0; i < n; i++) {
        cin >> v[i].x >> v[i].y;
        if (i >= 2) {
            flag = flag && parallel(v[i], v[i-1], v[i-1], v[i-2]) == 0;
        }
    }
    if (flag) {
        cout << "YES\n";
        return;
    } 
    for (int i = 0; i < n; i++) {
        v.push_back({v[i].x, v[i].y - 1});
        v.push_back({v[i].x-1, v[i].y});
        v.push_back({v[i].x-1, v[i].y - 1});
        v.push_back({v[i].x+1, v[i].y - 1});
    }
    int SUIJI_CNT = 1000;
    for (int i = 0; i < SUIJI_CNT; i++) {
        int a1 = suiji(0, n - 1);
        int a2 = suiji(0, v.size() - 1);
        if (a1 == a2) continue;
        int b1 = suiji(0, n - 1);
        int b2 = suiji(0, v.size() - 1);
        if (b1 == b2) continue;
        if (parallel(v[a1], v[a2], v[b1], v[b2]) == 0) continue;
        Point p = GetLineIntersection(v[a1], v[a2] - v[a1], v[b1], v[b2] - v[b1]);
        if (check(v, p, n)) {
            cout << "YES\n";
            return;
        }
    }

    cout << "NO\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T = 1;
    cin >> T;
    while (T--) solve();
    return 0;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值