2019UMS培训day5解题报告

T1:

链接:https://www.luogu.org/problem/T92563

$sol1$:把所有的加起来,减去个数恒为$2$的,再减去$2 \times (n-1)$,即为答案。使用快速幂处理,还要注意答案可能出现负数。

$sol2$:推出矩阵式子后用矩阵快速幂来维护。

代码$(sol1)$:

#include <bits/stdc++.h>
const int mod = 19260817;
typedef long long ll;
using namespace std;
ll n;
ll qpow(ll x, ll y) {
    ll ans = 1;
    while(y) {
        if(y & 1)
            ans = (ll)(ans % mod * x % mod) % mod;
        x = (ll)(x % mod * x % mod) % mod;
        y >>= 1;
    }
    return ans % mod;
}
int main() {
    cin >> n;
    cout << ((qpow(2, n) - (2 * n)) % mod + mod) % mod << endl;
    return 0;
}

T2:

链接:https://www.luogu.org/problem/T92564

$sol1$:使用一维差分,然后执行$y2-y1$次。

$sol2$:直接二维差分,用前缀和维护。

代码$(sol1)$:

#include <bits/stdc++.h>
const int MAXN = 1050;
using namespace std;
int n, m, x, y, xx, yy, a[MAXN][MAXN], f[MAXN][MAXN];
int read() {
    int x = 0;
    bool sign = false;
    char alpha = 0;
    while(!isdigit(alpha)) {
        sign |= alpha == '-';
        alpha = getchar();
    }
    while(isdigit(alpha)) {
        x = (x << 1) + (x << 3) + (alpha ^ 48);
        alpha = getchar();
    }
    return sign ? -x : x;
}
int main() {
    n = read();
    m = read();
    while(m--) {
        x = read();
        y = read();
        xx = read();
        yy = read();
        for(int i = y; i <= yy; i++) {
            a[xx + 1][i] --;
            a[x][i] ++;
        }
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            a[i][j] = a[i - 1][j] + a[i][j];
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

T3:

链接:https://www.luogu.org/problem/T92569

$sol1:$:由于$k$的数据范围很小,考虑枚举出$2^k$的所有情况。有个优化即为把与输入重复的去除。先异或,然后用$lowbit$数出不同的个数,统计即可。

题目中最坏情况如何统计?即先取最小值后取最大值。

$sol2$:多源最短路,$bfs$即可。

代码$(sol1)$:

#include <bits/stdc++.h>
const int INF = 1 << 30;
const int MAXN = 200050;
using namespace std;
int n, k, o, cnt, ans, num, cnt1, Min = INF, b[MAXN], c[MAXN];
bool vis[MAXN];
string s[MAXN];
char e;
int lowbit(int x) { return x & (-x); }
int main() {
    ios::sync_with_stdio(false);
    cin >> n >> k;
    for(int i = 1; i <= n; i++) {
        int p = 0;
        for(int j = k - 1; j >= 0; j--) {
            cin >> e;
            o = e - '0';
            p |= (o << j);
        }
        if(!vis[p]) {
            b[++cnt1] = p;
            vis[p] = true;
        }
    }
    for(int i = 0; i < (1 << k); i++) {
        if(!vis[i])
            c[++cnt] = i;
    }
    if(cnt == 0) {
        cout << "0" << endl;
        return 0;
    }
    for(int i = 1; i <= cnt; i++) {
        for(int j = 1; j <= cnt1; j++) {
            int res = b[j] ^ c[i];
            while(res > 0) {
                res -= lowbit(res);
                num++;
            }
            Min = min(Min, num);
            num = 0;
        }
        ans = max(ans, Min);
        Min = INF;
    }
    cout << ans << endl;
    return 0;
}

T4:

链接:https://www.luogu.org/problem/T92570

$sol$:直接暴力$bfs$加上个剪枝优化就行了。

代码:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
const int INF = 1 << 30;
const int MAXN = 1050;
const int dirx[] = {1, 0, 0, -1};
const int diry[] = {0, 1, -1, 0};
using namespace std;
struct node {
    int x, y, t;
};
queue<node> q;
struct node1{
    int x, y;
}p[MAXN << 1];
int t, n, x, y, tmax = INF;
bool vis[MAXN][MAXN];
int read (){
    int xx = 0;
    bool sign = false;
    char alpha = 0;
    while(!isdigit(alpha)) {
        sign |= alpha == '-';
        alpha = getchar();
    }
    while(isdigit(alpha)) {
        xx = (xx << 1) +(xx << 3) + (alpha ^48);
        alpha = getchar();
    }
    return sign ? -xx : xx;
}
bool check(int x, int y) { return x < 1 || x > n || y < 1 || y > n; }
bool bfs() {
    int nowt = 0;
    q.push((node){1, 1, 0});
    vis[1][1] = true;
    while(!q.empty()) {
        node now = q.front();
        q.pop();
        int x = now.x, y = now.y, t = now.t;
        if(t != nowt) {
            vis[p[t].x][p[t].y] = true;
            nowt = t;
        }
        if(x == n && y == n)
            return true;
        else if(vis[n][n] && t == tmax)
            return false;
        for(int i = 0; i < 4; i++) {
            int dx = x + dirx[i], dy = y + diry[i];
            if(check(dx, dy) || vis[dx][dy] || (dx == p[t + 1].x && dy == p[t + 1].y && (dx != n && dy != n)))
                continue;
            vis[dx][dy] = true;
            q.push((node){dx, dy, t + 1});
        }
    }
    return false;
}
void init() {
    tmax = INF;
    while(!q.empty())
        q.pop();
    for(int i = 1; i <= n; i++) {
        p[i].x = p[i].y = 0;
        for(int j = 1; j <= n; j++)
            vis[i][j] = false;
    }
}
int main() {
    t = read();
    while(t--) {
        n = read();
        for(int i = 1; i <= (n << 1) - 2; i++) {
            x = read();
            y = read();
            if(x == n && y == n && tmax == INF)
                tmax = i;
            p[i].x = x;
            p[i].y = y;
        }
        bfs() ? printf("Yes\n") : printf("No\n");
        init();
    }
    return 0;
}

 

posted @ 2019-08-08 09:04  BeyondLimits  阅读(197)  评论(0编辑  收藏  举报