2024.9.8 CCPC网络预选赛

https://codeforces.com/gym/105336/
A.军训I
思路:我们分析最多不重复方案为13。 13=1+4+4*2。
首先排除k>13无解,排除k=8,10,12无解。
k=5,7,9,11,13难理解。

#include <bits/stdc++.h>

#define int long long
using namespace std;
typedef long long i64;
typedef pair<int, int> PII;

const int N = 1e3 + 10, p = 998244353;
//int dp[N][N][N];
char g[N][N];

int lowbit(int x) { return x & (-x); }

void sc(int n, int m) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cout << g[i][j];
        }
        cout << '\n';
    }
}

void solve() {
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            g[i][j] = '-';

    if (k > 13 || (k >= 8 && k % 2 == 0) || (k == 5 && gcd(n, m) == 1)) {
        cout << "No\n";
        return;
    }

    if (k == 1) {
        cout << "Yes\n";
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                g[i][j] = '*';

        sc(n,m);
    } else if (k == 2) {
        if (n == 1 && m == 1) {
            cout << "No\n";
            return;
        }//第一行或第一列为*
        cout << "Yes\n";
        if (n > 1) {
            for (int i = 1; i <= m; i++) g[1][i] = '*';
            sc(n,m);
        } else {
            for (int i = 1; i <= n; i++) g[i][1] = '*';
            sc(n,m);
        }
    } else if (k == 3) {
        if (n < 3 && m < 3) {
            cout << "No\n";
            return;
        }//第二行或第二列为*
        cout << "Yes\n";
        if (n >= 3) {
            for (int i = 1; i <= m; i++) g[2][i] = '*';
            sc(n,m);
        } else {
            for (int i = 1; i <= n; i++) g[i][2] = '*';
            sc(n,m);
        }
    } else if (k == 4) {
        if (n == 1 || m == 1) {
            cout << "No\n";
            return;
        }
        if (n >= 2 && m >= 2) {
            cout << "Yes\n";
            g[1][1] = '*';
            sc(n,m);
        }
    } else if (k == 5) {
        cout << "Yes\n";
        int k = gcd(n, m);
        int t = 1;
        for (int i = 1; i <= n; i++) {
            for (int j = t; j <= m; j = j + k) g[i][j] = '*';
            t++;
            if (t == k + 1) t = 1;
        }
        sc(n,m);
    } else if (k == 6) {
        //在行或列>=3中选,把*放(2,1) 或者 (1,2)
        if (n >= 3 && m >= 2 || n >= 2 && m >= 3) {
            cout << "Yes\n";
            if (n >= 3) g[2][1] = '*';
            else g[1][2] = '*';
            sc(n,m);
        } else {
            cout << "No\n";
            return;
        }
    } else if (k == 7) {
        if (n >= 3 && m >= 2 || n >= 2 && m >= 3) { //(2,1) + 第一行 或者 (1,2) + 第一列
            cout << "Yes\n";
            if (n >= 3) {
                g[1][2] = '*';
                for (int i = 2; i <= n; i++) g[i][1] = '*';
            } else {
                g[2][1] = '*';
                for (int i = 2; i <= m; i++) g[1][i] = '*';
            }
            sc(n,m);
        } else {
            cout << "No\n";
            return;
        }
    } else if (k == 9) {
        if (n >= 3 && m >= 3) { //(2,2)
            cout << "Yes\n";
            g[2][2] = '*';
            sc(n,m);
            return;
        } else if (n >= 3 && m == 2 || n == 2 && m >= 3) { //(1,1)(n,m)
            cout << "Yes\n";
            g[1][1] = g[n][m] = '*';
            sc(n,m);
        } else {
            cout << "No\n";
            return;
        }
    } else if (k == 11) {
        if (n >= 2 && m >= 4 || n >= 4 && m >= 2) {
            cout << "Yes\n";
            if (n >= 2 && m >= 4) { //(1,2)(1,4)(2,1)
                g[1][2] = g[2][1] = g[1][4] = '*';
                sc(n,m);
            } else { //(1,2)(4,1)(2,1)
                g[1][2] = g[2][1] = g[4][1] = '*';
                sc(n,m);
            }
        } else if (n == 3 && m == 3) { //(1,1)(3,2)
            cout << "Yes\n";
            g[1][1] = g[3][2] = '*';
            sc(n,m);
        } else {
            cout << "No\n";
            return;
        }
    } else if (k == 13) {
        if (n >= 3 && m >= 3) { //(1,3)(3,1) || (1,1)(3,3)
            cout << "Yes\n";
            g[1][3] = g[3][1] = '*';
            sc(n,m);
        } else {
            cout << "No\n";
            return;
        }
    }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值