1. 程式人生 > 其它 >2018 Chinese Multi-University Training, Nanjing U Contest

2018 Chinese Multi-University Training, Nanjing U Contest

A:Character Encoding
插板法+容斥
https://blog.csdn.net/codeswarrior/article/details/81906367?utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1.control
講的特別好

int fact[maxn], finv[maxn], inv[maxn];
void init() {
    fact[0] = fact[1] = finv[0] = finv[1] = inv[0] = inv[1] = 1;
    for(int i = 2; i < maxn; ++ i) {
        fact[i] = fact[i - 1] * i % mod;
        inv[i] = (mod - mod / i) * inv[mod % i] % mod;
        finv[i] = finv[i - 1] * inv[i] % mod;
    }
}
inline int C(int n, int m) {
    if(n < 0 || m < 0 || m > n) return 0;
    return fact[n] * finv[m] % mod * finv[n - m] % mod;
}
inline void qmod(int &a) {
    while(a >= mod)    a -= mod;
}

signed main() {
    init();
    int t = rd();
    while(t--) {
        int n = rd(), m = rd(), k = rd();
        int ans = C(k + m - 1, m - 1);
        for(int i = 1, f = -1; i * n <= k; ++ i, f = -f)
            qmod(ans += f * C(k - i * n + m - 1, m - 1) * C(m, i) % mod + mod);
        printf("%lld\n", ans);
    }
    return 0;
}

D: Parentheses Matrix
打標找規律的構造題,規模比較大,注意的是剪枝

int ans = 0, n, m, cnt = 0;
int c[maxn], r[maxn];
char mp[202][202];
void dfs(int x, int y) {
    cnt ++;
    if(cnt % 100000000 == 0)   printf("%lld\n", cnt);
    if(x == n - 1) {
        int res = 0;
        for(int i = 0; i < n; ++ i) if(r[i])   res ++;
        for(int i = 0; i < m; ++ i) if(c[i])   res ++;
        if(n + m - res < ans)   return ;
        res = 0;
        for(int i = 0; i < n; ++ i) {
            int cnt = 0;
            for(int j = 0; j < m; ++ j) if(mp[i][j] == '(') cnt ++;
                                        else if(cnt)    cnt --;
                                        else {cnt = -1; break;}
            if(cnt == 0)    res ++;
        }
        for(int i = 0; i < m; ++ i) {
            int cnt = 0;
            for(int j = 0; j < n; ++ j) if(mp[j][i] == '(') cnt ++;
                                        else if(cnt)    cnt --;
                                        else {cnt = -1; break;}
            if(cnt == 0)    res ++;
        }
        //if(res == ans) {
        //    for(int i = 0; i < n; ++ i) puts(mp[i]);
        //    dbg(ans); puts("");
        //}
        if(res > ans) {
            for(int i = 0; i < n; ++ i) {
                for(int j = 0; j < m; ++j) printf("%c", mp[i][j]);
                puts("");
            }
            puts("");
            ans = res;
            dbg(ans);
        }
        return;
    }
    mp[x][y] = '('; r[x] ++;    c[y] ++;
    dfs(x + (y + 1) / m, (y + 1) % m);
    mp[x][y] = '('; r[x] --;    c[y] --;
    mp[x][y] = ')'; r[x] --;    c[y] --;
    dfs(x + (y + 1) / m, (y + 1) % m);
    mp[x][y] = ')'; r[x] ++;    c[y] ++;
}

signed main() {
    int t = rd();
    while(t--) {
        n = rd(), m = rd();
        for(int i = 0; i <= n; ++ i)    r[i] = 0; r[0] = r[n - 1] = m;
        for(int i = 0; i <= m; ++ i)    c[i] = 0;
        for(int i = 0; i <= n; ++ i)    mp[i][m] = '\0';
        //ans = 0;
        ans = 8;
        for(int j = 0; j < m; ++ j) mp[0][j] = '(', mp[n - 1][j] = ')';
        //dfs(1, 0);
        //dbg(ans);
        if(n & m & 1)   for(int i = 1; i <= n; ++ i)    for(int j = 0; j <= m; ++ j)    printf("%c", "(\n"[j == m]);
        else if(n & 1)  for(int i = 1; i <= n; ++ i)    {for(int j = 0; j < m; ++ j)    printf("%c", "()"[j % 2]); puts("");}
        else if(m & 1)  for(int i = 1; i <= n; ++ i)    {for(int j = 0; j < m; ++ j)    printf("%c", "()"[i % 2 == 0]); puts("");}
        else {
            int x = n, y = m;
            if(x > y)   swap(x, y);
            for(int j = 0; j < y; ++ j) mp[0][j] = '(', mp[x - 1][j] = ')';
            if(x == 4) for(int j = 0; j < y; ++ j) mp[1][j] = "()"[j >= (y >> 1)], mp[2][j] = ")("[j >= (y >> 1)];
            else if(x > 4){
                for(int i = 1; i < x - 1; ++ i) {
                    if(i & 1)   for(int j = 0; j < y; ++ j) mp[i][j] = "()"[j % 2];
                    else        for(int j = 0; j < y; ++ j) mp[i][j] = "()"[(j % 2 == 0 && j != 0) || j == y - 1];
                }
            }
            if(n > m)   for(int i = 0; i < x; ++ i) for(int j = i + 1; j < y; ++ j) swap(mp[i][j], mp[j][i]);
            for(int i = 0; i < n; ++ i) mp[i][m] = '\0';
            for(int i = 0; i < n; ++ i) puts(mp[i]);
        }
    }
    return 0;
}

/*
case: h = 2
(((((
)))))

case: h = 4
((((((
((()))
)))(((
))))))

case: h > 6
((((((
()()()
(()())
()()()
(()())
))))))

one case can swap to another case
*/