AtCoder Beginner Contest 405

数学,优化求和顺序

就是常见的结论题。

\[\left( \sum_{1 \leq i \leq N} A_i \right)^2 = \sum_{1 \leq i \leq N} A_i^2 + 2 \sum_{1 \leq i < j \leq N} A_i A_j \]

\[S = \sum_{1 \leq i \leq N} A_i \]

\[Q = \sum_{1 \leq i \leq N} A_i^2 \\ \]

\[\sum_{1 \leq i < j \leq N} A_i A_j = \frac{S^2 - Q}{2} \]

#include <iostream>
#include <vector>
using namespace std;
long long f(const vector<int>& A) {
    long long S = 0; 
    long long Q = 0; 
    for (int x : A) {
        S += x;
        Q += (long long)x * x;
    }
    return (S * S - Q) / 2;
}

int main() {
    int N;
    cin >> N;
    vector<int> A(N);
    for (int i = 0; i < N; i++) {
        cin >> A[i];
    }
    cout << f(A) << endl;
    return 0;
}

BFS,模拟

按照题意模拟即可,即将每个 \(E\) 加入队列,然后向四个方向遍历所有点,并且更新方向。

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
//#define int long long
inline int rd(){
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
        x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}
#define rd rd()

void wt(int x){
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        wt(x / 10);
    putchar(x % 10 + '0');
    return;
}
void wt(char x){
    putchar(x);
}
void wt(int x, char k){
    wt(x),putchar(k);
}

namespace Star_F{
    const int N = 1005;
    int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
    char c[N][N], ans[N][N], dir[] = {'v', '^', '>', '<'};
    int dis[N][N];
    void Main(){
        int H, W;
        cin >> H >> W;
        for (int i = 1; i <= H; i++)
            cin >> c[i] + 1;
        memset(dis, -1, sizeof(dis));
        queue<PII> q;
        for (int i = 1; i <= H; i++)
            for (int j = 1; j <= W; j++)
                if (c[i][j] == 'E')
                    dis[i][j] = 0,q.push({i, j});
        while (!q.empty()){
            int x, y;
            x = q.front().fi, y = q.front().se;
            q.pop();
            for (int i = 0; i < 4; i++){
                int nx = x + dx[i], ny = y + dy[i];
                if (nx >= 1 && nx <= H && ny >= 1 && ny <= W && c[nx][ny] == '.' && dis[nx][ny] == -1){
                    dis[nx][ny] = dis[x][y] + 1;
                    ans[nx][ny] = dir[i]; 
                    q.push({nx, ny});
                }
            }
        }
        for (int i = 1; i <= H; i++){
            for (int j = 1; j <= W; j++){
                if (c[i][j] == '.')
                    cout << ans[i][j];
                else
                    cout << c[i][j];
            }
            cout << endl;
        }
    }
}

signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ClockA;
    int T=1;
    // T=rd;
    while(T--) Star_F::Main();
    // ClockB;
    return 0;
}

数论,组合数学

假设第一个葡萄的位置是 \(i\),那么前 \(i-1\) 个位置由 \(a\) 和苹果、\(b\) 个橘子、\(x = i - 1 - a - b\) 个香蕉组成。后 \(n-i\) 个位置就由 \(c-x\) 个香蕉和剩下的葡萄组成。

\(i-1\) 个只需要确定橘子的摆放方案,会发现苹果和香蕉的方案就唯一了(因为苹果必须在香蕉前面)所以方案数就是 \(\binom{i-1}{b}\)

\(n-i\) 个只需要确定香蕉的摆放方案,剩下的就只能摆葡萄了,方案数是 \(\binom{n-i}{c-x}\)

答案为 \(\binom{i-1}b \times \binom{n-i}{c-x}\)

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
#define int long long
inline int rd(){
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
        x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}
#define rd rd()

void wt(int x){
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        wt(x / 10);
    putchar(x % 10 + '0');
    return;
}
void wt(char x){
    putchar(x);
}
void wt(int x, char k){
    wt(x),putchar(k);
}

namespace Star_F{
    const int N = 4e6 + 5, mod = 998244353;
    ll fac[N], inv[N];
    ll qpow(ll a,ll b){
        ll res = 1;
        while(b){
            if(b&1)
                res = res * a % mod;
            a = a * a % mod;
            b >>= 1;
        }
        return res;
    }

    void init(){
        fac[0] = 1, inv[0] = 1;
        for (int i = 1; i < N; i++)
            fac[i] = fac[i - 1] * i % mod;
        inv[N - 1] = qpow(fac[N - 1], mod - 2);
        for (int i = N - 2; i >= 1; i--)
            inv[i] = inv[i + 1] * (i + 1) % mod;
    }

    ll C(ll n,ll m){
        if(n<0||m<0)
            return 0;
        if(m>n)
            return 0;
        return fac[n] * inv[m] % mod * inv[n - m]  % mod;
    }
    void Main(){
        init();
        ll a = rd, b = rd, c = rd, d = rd;
        ll res = 0, n = a + b + c + d;
        for(int i = a+b+1; i <= n - d + 1; i++){
            int x = i - 1 - a - b;
            res = (res + C(i - 1, b) * C(n - i, c - x) % mod) % mod;
        }
        cout << res << endl;
    }

}

signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ClockA;
    int T=1;
    // T=rd;
    while(T--) Star_F::Main();
    // ClockB;
    return 0;
}
posted @ 2025-05-10 21:36  Star_F  阅读(33)  评论(0)    收藏  举报