YACS 2023年9月月赛 乙组 题解

题目链接1

题目链接2

题目链接3

题目链接4

 

T1

折半水题,不多说了,代码:

#include <bits/stdc++.h>
#define For(i, a, b) for (int i = (a); i <= (b); i ++)
#define int long long
using namespace std;
int n;
int a[41];
vector <int> v1, v2;
void dfs1 (int x, int s) {
    if (x == n / 2 + 1) {
        v1.push_back (s);
        return;
    }
    dfs1 (x + 1, s + a[x]);
    dfs1 (x + 1, s);
}
void dfs2 (int x, int s) {
    if (x == n + 1) {
        v2.push_back (s);
        return;
    }
    dfs2 (x + 1, s + a[x]);
    dfs2 (x + 1, s);
}
signed main () {
    cin >> n;
    For (i, 1, n) cin >> a[i];
    if (n == 1) {
        cout << (a[1] > 0);
        return 0;
    }
    dfs1 (1, 0);
    dfs2 (n / 2 + 1, 0);
    sort (v1.begin (), v1.end () );
    sort (v2.begin (), v2.end (), greater <int> () );
    int ans = 0, r = -1;
    For (i, 0, v1.size () - 1) {
        while (r != v2.size () - 1 && v2[r + 1] + v1[i] > 0) ++ r;
        ans += r + 1;
    }
    cout << ans;
    return 0;
}

 

T2

在 NFLS 集训完后遇到的第一个是需要用我在 NFLS 学到的套路的题。

类似 dijkstra 的做法每次取出当前路径上经过障碍物最少的那个点,更新周围的点,其实就是把地图抽象成了一个最短路问题。

代码:

#include <bits/stdc++.h>
#define For(i, a, b) for (int i = (a); i <= (b); i ++)
#define int long long
using namespace std;
int n, m;
char a[1005][1005];
int f[1005][1005];
const int dx[5] = {0, 1, -1, 0, 0}, dy[5] = {0, 0, 0, 1, -1};
struct Node {
    int x, y, c;
    bool operator < (const Node &s) const {return c > s.c;}
};
priority_queue <Node> q;
signed main () {
    memset (f, 0x3f, sizeof f);
    cin >> n >> m;
    For (i, 1, n) For (j, 1, m) cin >> a[i][j];
    q.push ({1, 1, 0});
    f[1][1] = 0;
    while (!q.empty () ) {
        int x = q.top ().x, y = q.top ().y, c = q.top ().c;
        q.pop ();
        For (i, 1, 4) {
            int fx = x + dx[i], fy = y + dy[i];
            if (fx < 1 || fy < 1 || fx > n || fy > m) continue;
            int cur = f[x][y] + (a[fx][fy] == '*');
            if (f[fx][fy] > cur) {
                f[fx][fy] = cur;
                q.push ({fx, fy, cur});
            }
        }
    }
    cout << f[n][m];
    return 0;
}

 

T3

题面明显提示是一道拓扑排序,建好图之后求一遍有向无环图最长路即可,就是个 DP。

代码:

#include <bits/stdc++.h>
#define For(i, a, b) for (int i = (a); i <= (b); i ++)
#define int long long
using namespace std;
int n, m, ans;
int d[200005], f[200005], t[200005];
vector <int> G[200005], e[200005];
queue <int> q;
signed main () {
    cin >> n >> m;
    For (i, 1, n) cin >> t[i];
    For (i, 1, m) {
        int x, y;
        cin >> x >> y;
        G[x].push_back (y);
        e[y].push_back (x);
        d[y] ++;
    }
    For (i, 1, n) if (d[i] == 0) q.push(i);
    while (!q.empty () ) {
        int u = q.front ();
        q.pop ();
        f[u] = t[u];
        for (int v : e[u]) f[u] = max (f[u], f[v] + t[u]);
        ans = max (ans, f[u]);
        for (int v : G[u]) {
            d[v] --;
            if (d[v] == 0) q.push (v);
        }
    }
    cout << ans;
    return 0;
}

 

T4

好题,观察到 $m$ 很小,但是我不知道该怎么做,于是就打了表过了。

代码:

#include <bits/stdc++.h>
#define For(i, a, b) for (int i = (a); i <= (b); i ++)
#define int long long
using namespace std;
int n, m;
int pre[101] = {1, 682498929,491101308,76479948,723816384,67347853,27368307,625544428,199888908,888050723,927880474,281863274,661224977,623534362,970055531,261384175,195888993,66404266,547665832,109838563,933245637,724691727,368925948,268838846,136026497,112390913,135498044,217544623,419363534,500780548,668123525,128487469,30977140,522049725,309058615,386027524,189239124,148528617,940567523,917084264,429277690,996164327,358655417,568392357,780072518,462639908,275105629,909210595,99199382,703397904,733333339,97830135,608823837,256141983,141827977,696628828,637939935,811575797,848924691,131772368,724464507,272814771,326159309,456152084,903466878,92255682,769795511,373745190,606241871,825871994,957939114,435887178,852304035,663307737,375297772,217598709,624148346,671734977,624500515,748510389,203191898,423951674,629786193,672850561,814362881,823845496,116667533,256473217,627655552,245795606,586445753,172114298,193781724,778983779,83868974,315103615,965785236,492741665,377329025,847549272,698611116};
const int mod = 1000000007;
int fac (int x) {
    int res = pre[x / 10000000];
    For (i, x / 10000000 * 10000000 + 1, x) {
        res *= i;
        res %= mod;
    }
    return res;
}
int q_pow (int x, int y) {
    if (y == 0) return 1;
    if (y & 1) return x * q_pow (x * x % mod, y >> 1) % mod;
    return q_pow (x * x % mod, y >> 1);
}
signed main () {
    cin >> n >> m;
    cout << fac (n) * q_pow (fac (m), mod - 2) % mod * q_pow (fac (n - m), mod - 2) % mod;
    return 0;
}

 

posted @ 2023-10-16 22:04  Xy_top  阅读(57)  评论(0编辑  收藏  举报