2021辽宁省大学生程序设计竞赛 题解

A

不会

B

不会

C

因为 n = 8 所以我直接选择了暴力
先排个序 然后观察 对于 i 来说 往前 往后 最多能有几个会被传染 记录一下最大最小值就行了

#include <bits/stdc++.h>
#define pb emplace_back
#define xx first
#define yy second
#define in(x) scanf("%d",&x)
#define lin(x) scanf("%lld",&x)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 2e6+10;
const int M = N*2;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
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;}
int n,m,k;
int A[N],B[N];
char str[N];
signed main(){
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
    int T = 1;  in(T);
    while(T--){
        in(n);
        for(int i = 1;i <= n;i++)
            in(A[i]);
        sort(A+1,A+n+1);
        int mn = n,mx = 0;
        for(int i = 1;i <= n;i++){
            int cnt = 0,base = A[i];
            for(int j = i-1;j >= 1;j--){
                if(base - A[j] <= 2)    cnt++,base = A[j];
                else    break;
            }
            base = A[i];
            for(int j = i+1;j <= n;j++){
                if(A[j] - base <= 2)    cnt++,base = A[j];
                else    break;
            }
            cnt++;
            mn = min(mn,cnt),mx = max(mx,cnt);
        }
        cout << mn << ' ' << mx << endl;
    }
    return 0;
}

D

挺简单的一道题
首先如果斜着走比直着走两次要优 那么肯定是斜着走 反之 就直接直着走
第一种情况下 斜着走完了。肯定会剩下一段大直道 现在考虑 是斜向上 再 斜向下 走 还是 直接向右走两步 好 所以比较下 x 和 y 就行 但要注意 如果要斜着走 必须满足 min(n,m) > 1

#include <bits/stdc++.h>
#define pb emplace_back
#define xx first
#define yy second
#define in(x) scanf("%d",&x)
#define lin(x) scanf("%lld",&x)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 2e6+10;
const int M = N*2;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
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;}
int n,m,k;
int A[N];
char str[N];
signed main(){
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
    int T = 1;  in(T);
    ll x,y;
    while(T--){
        scanf("%d %d %lld %lld",&n,&m,&x,&y);
        if(n > m)   swap(n,m);
        ll ans = 0;
        if(2*x >= y){   // 斜着走更好
            if(n == 1){
                ans += x * (m-1);
            }else{    // 斜向上 再 斜向下
                ans += y * (n-1);
                m -= n;
                if(x >= y){    // 斜着走更好
                    ans += y * (m/2*2);
                    if(m&1) ans += x;    // 最后一步直着走
                } else  ans += x * m;
            }
        }else{
            ans = x * (n + m - 2);
        }
        cout << ans << endl;
    }
    return 0;
}

E

答案很快就能想到是

for i in range(1, t - 3):
    boys = t - i
    girls = i
    ans += C(n, boys) * C(m, girls)

但由于数据过大 所以需要用高精度python

N = 35
fact = []


def init():
    fact.append(1)
    fact.append(1)
    for i in range(2, N):
        fact.append(fact[i - 1] * i)


def C(a, b):
    if b > a:
        return 0
    return fact[a] // (fact[b] * fact[a - b])


if __name__ == '__main__':
    init()
    str = input()
    n = int(str.split()[0])
    m = int(str.split()[1])
    t = int(str.split()[2])

    ans = 0
    if n < 4 or m < 1:
        print(0)
    else:
        for i in range(1, t - 3):
            b = t - i
            ans += C(n, b) * C(m, i)
        print(ans)

F

阅读理解
只要除第一个字母外 出现了小写字母 就反转

#include <bits/stdc++.h>
#define pb emplace_back
#define xx first
#define yy second
#define in(x) scanf("%d",&x)
#define lin(x) scanf("%lld",&x)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 2e6+10;
const int M = N*2;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
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;}
int n,m,k;
int A[N];
char str[N];
signed main(){
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
    int T = 1;
    while(T--){
        scanf("%s",str);
        n = strlen(str);
        bool flag = 1;
        for(int i = 1;i < n;i++){
            if(str[i] >= 'a')   flag = 0;
        }
        if(flag){
            for(int i = 0;i < n;i++){
                if(str[i] >= 'a')   printf("%c",str[i]-('a'-'A'));
                else    printf("%c",str[i]+('a'-'A'));
            }
        }else{
            for(int i = 0;i < n;i++)    printf("%c",str[i]);
        }

    }
    return 0;
}

G

方法一:判断字符串长度
方法二:python

n = eval(input())

if n<= 127:
    print("byte")
elif n<=32767:
    print("short")
elif n <= 2147483647:
    print("int")
elif n<=9223372036854775807:
    print("long")
else:
    print("BigInteger")

H

不会

I

挺简单的一道线段树 队友写的

#define xx first
#define yy second
#include <bits/stdc++.h>
#define in(x) scanf("%d", &x)
#define lin(x) scanf("%lld", &(x))
#define rep(i, x, y) for(auto i = (x); i <= (y); i ++ )
#define dep(i, x, y) for(auto i = (x); i >= (y); i -- )
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 300010;
const int INF = 0x3f3f3f3f;
const int mo = 1e9 + 7;
struct Node{
    int l, r;
    int w;
}node[N<<2];
int a[N];
int b;
void pushUp(int rt) {
    node[rt].w = node[rt<<1].w + node[rt<<1|1].w;
}
void build(int rt, int l, int r) {
    node[rt] = {l, r};
    if(l == r) {
        return;
    }
    int mid = l + r >> 1;
    build(rt<<1, l, mid);
    build(rt<<1|1, mid + 1, r);
}

void add(int rt, int id, int num) {
    if(node[rt].l == node[rt].r) {
        node[rt].w = num;
        return;
    }
    int mid = node[rt].l + node[rt].r >> 1;
    if(id <= mid) {
        add(rt << 1, id, num);
    } else {
        add((rt << 1)|1, id, num);
    }
    pushUp(rt);
}
int query(int rt, int ql, int qr) {
    int l = node[rt].l, r = node[rt].r;
    if(ql <= l && qr >= r) return node[rt].w;
    int mid = l + r >> 1, sum = 0;
    if(ql <= mid) sum = query(rt << 1, ql, qr);
    if(qr > mid) sum += query((rt << 1)|1, ql, qr);
    return sum;
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("data/1.in", "r", stdin);
    #endif
    int m, q; in(m), in(q);
    
    build(1, 1, m);
    int idx = 0, last = 0;
    rep(i, 1, m) {
        in(a[i]);
    }

    a[0] = 0, a[m + 1] = INF;
    rep(i, 1, m) {
        if(a[i] <= a[i + 1] && a[i] >= a[i - 1]) {
            add(1, ++idx, 0);
        } else {
            add(1, ++ idx, 1);
        }
    }

    rep(i, 1, q) {
        int opt, x, y;
        in(opt), in(x), in(y);
        if(opt == 1) {
            a[x] = y;
            rep(j, x - 1, x + 1) {
                if(j < 1 || j > m) continue;
                if(a[j] <= a[j + 1] && a[j] >= a[j - 1]) {
                    add(1, j, 0);
                } else {
                    add(1, j, 1);
                }
            }
            
        } else {
            if(x == y) puts("Yes");
            else if(x + 1 == y) {
                if(a[x] <= a[y]) {
                    puts("Yes");
                } else {
                    puts("No");
                }
            } else if(query(1, x + 1, y - 1) == 0) {
                puts("Yes");
            } else {
                puts("No");
            }
            
        }
        
    }
    return 0;
}

J

很明显可以看出第n+1列上的棋子个数跟第1列的棋子个数是一样的 所以我们可以得到两个式子:\sum_{i = 0}^{n-1}a_{i} = kans = \prod_{i=0}^{m-1}C_{n}^{a_{i\%n}}

#include <bits/stdc++.h>
#define pb emplace_back
#define xx first
#define yy second
#define int ll
#define in(x) scanf("%lld",&x)
#define lin(x) scanf("%lld",&x)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 100+10;
const int M = N*2;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
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;}
int inv(int x){
    return qpow(x,MOD-2);
}
int n,m,k;
int A[N],C[N],times[N],ans[N][2];
int dp[N][N*N];
signed main(){
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
    int T = 1;
    while(T--){
        in(n),in(m),in(k);
        C[0] = 1;   // C(n,0)
        for(int i = 1;i <= n;i++){
            C[i] = C[i-1] * (n + 1 - i) % MOD * inv(i) % MOD;
        }

        for(int i = 0;i <= n;i++){  // ai的出现次数
            if(m % n >= i)  times[i] = m/n+1;
            else    times[i] = m/n;
        }
        dp[0][0] = 1;
        for(int i = 0;i <= n;i++){  // 贡献
            ans[i][1] = qpow(C[i],m/n+1);
            ans[i][0] = qpow(C[i],m/n);
        }

        for(int i = 1;i <= n;i++){
            for(int j = 0;j <= k;j++){
                for(int t = 0;t <= min(j,n);t++){
                    dp[i][j] = (dp[i][j] + dp[i-1][j-t] * ans[t][times[i] == (m/n+1)] % MOD) % MOD;
                }
            }
        }
        cout << dp[n][k] << endl;
    }
    return 0;
}


K

不会

L

签到题
输出 min(x,18)就行

M

挺裸的一道拓扑排序题

#include <bits/stdc++.h>
#define pb emplace_back
#define xx first
#define yy second
#define in(x) scanf("%d",&x)
#define lin(x) scanf("%lld",&x)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 500+10;
const int M = N<<1;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
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;}
int n,m,k;
bool st[N];
int ind[N],out[N];
int h[N],ne[M],e[M],idx;
void add(int a,int b){
    e[idx] = b,ne[idx] = h[a],h[a] = idx++;
    ind[b]++,out[a]++;
}
int q[M];
int hh = 0,tt = 0;
void topsort(){
    for(int i = '0';i <= 'z';i++)
        if(st[i] && !ind[i])  q[tt++] = i;

    while(hh != tt){
        int t = q[hh++];
        char ch = t;
        for(int i = h[t]; ~i;i = ne[i]){
            int j = e[i];
            ch = j;
            ind[j]--;
            if(!ind[j])  q[tt++] = j;
        }
    }
}
signed main(){
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
    int T = 1;
    while(T--){
        memset(h,-1,sizeof h);
        in(n);
        char str[5];
        int a,b,c;
        for(int i = 1;i <= n;i++){
            scanf("%s",str);
            b = str[0],a = str[2],c = str[3];
            add(a,b),add(b,c);
            st[a] = st[b] = st[c] = 1;
        }
        int cnt = 0;
        for(int i = '0';i <= 'z';i++){
            if(st[i])   cnt++;
        }
        topsort();
        if(tt == cnt){
            for(int i = 0;i < tt;i++){
                char tp = q[i];
                printf("%c",tp);
            }
        } else  puts("No Answer");
    }
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容