牛客训练赛45

博客记录了ACM相关问题的解题思路,包括记录每个Q、A后面最近的Q、A位置和个数,判断ALice是否能赢并枚举删掉白棋的情况,以及通过打表找规律来解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A
记录每个Q、A后面最近的Q、A位置和个数

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e3 + 5;
int f[maxn][3], cnt[maxn][3];
char str[maxn];
int main()
{
    scanf("%s", str);
    int n = strlen(str);
    for(int i = n; i >= 1; --i)
        str[i] = str[i - 1];
    memset(f, -1, sizeof(f));
    memset(cnt, 0, sizeof(cnt));
    for(int i = n - 1; i >= 0; --i) {
        if(str[i + 1] == 'Q') {
            f[i][0] = i + 1, f[i][1] = f[i + 1][1];
            cnt[i][0] = cnt[i + 1][0] + 1, cnt[i][1] = cnt[i + 1][1];
        }
        else if(str[i + 1] == 'A') {
            f[i][1] = i + 1, f[i][0] = f[i + 1][0];
            cnt[i][0] = cnt[i + 1][0], cnt[i][1] = cnt[i + 1][1] + 1;
        }
        else {
            f[i][0] = f[i + 1][0], f[i][1] = f[i + 1][1];
            cnt[i][0] = cnt[i + 1][0], cnt[i][1] = cnt[i + 1][1];
        }
    }
    ll ans = 0;
    for(int i = f[0][0]; i <= n && i >= 1; i = f[i][0]) {
        for(int j = f[i][1]; j != -1; j = f[j][1]) {
            if(j - i <= 1) continue;
            if(f[j][0] < 0 || f[j][0] > n) continue;
            if(f[j][0] - j > 1) ans += cnt[f[j][0] - 1][0];
            else if(f[f[j][0]][0] == -1) continue;
            else ans += cnt[f[f[j][0]][0] - 1][0];
        }
    }
    cout << ans << endl;
}

B
判断ALice是否能赢,若能赢枚举删掉白棋能不能赢

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5;
char ch[maxn][maxn];
int dir[8][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
bool check() {
    for(int i = 0; i < 3; ++i) {
        for(int j = 0; j < 3; ++j) {
            if(ch[i][j] == '#') {
                for(int k = 0; k < 8; ++k) {
                    int x = i + dir[k][0], y = j + dir[k][1];
                    if(x < 0 || x > 2) continue;
                    if(y < 0 || y > 2) continue;
                    if(ch[x][y] != 'W') continue;
                    int xx = x + dir[k][0], yy = y + dir[k][1];
                    if(xx < 0 || xx > 2) continue;
                    if(yy < 0 || yy > 2) continue;
                    if(ch[xx][yy] != 'W') continue;
                    return true;
                }
            }
            else if(ch[i][j] == 'W') {
                for(int k = 0; k < 8; ++k) {
                    int x = i + dir[k][0], y = j + dir[k][1];
                    if(x < 0 || x > 2) continue;
                    if(y < 0 || y > 2) continue;
                    if(ch[x][y] == 'W') {
                        int xx = x + dir[k][0], yy = y + dir[k][1];
                        if(xx < 0 || xx > 2) continue;
                        if(yy < 0 || yy > 2) continue;
                        if(ch[xx][yy] == '#') return true;
                    }
                    else if(ch[x][y] == '#') {
                        int xx = x + dir[k][0], yy = y + dir[k][1];
                        if(xx < 0 || xx > 2) continue;
                        if(yy < 0 || yy > 2) continue;
                        if(ch[xx][yy] == 'W') return true;
                    }
                }
            }
        }
    }
    return false;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--) {
        for(int i = 0; i < 3; ++i) cin >> ch[i];
        if(check()) {
            bool flg = false;
            for(int i = 0; i < 3; ++i) {
                for(int j = 0; j < 3; ++j) {
                    if(ch[i][j] == 'W') {
                        ch[i][j] = '#';
                        if(!check()) {
                            flg = true;
                            break;
                        }
                        ch[i][j] = 'W';
                    }
                }
            }
            if(flg) cout << "Emmm" << endl;
            else cout << "Alice" << endl;
        }
        else cout << "Bob" << endl;
    }
}

C
打表找规律

作者:小乔(☆_☆)
链接:https://ac.nowcoder.com/discuss/186550?type=101&order=0&pos=1&page=1
来源:牛客网

#include<bits/stdc++.h>
using namespace std;
bool vis[20];
int a[20];
void f(int x)
{
    printf("Case: %d\n",x);
    for(int i=0;i<x;i++)
        a[i]=i;
    int res=0;
    while(1)
    {
        int now=0,tot=1;
        memset(vis,false,sizeof(vis));
        vis[0]=true;
        while(!vis[(now+a[now])%x])
        {
            now=(now+a[now])%x;
            vis[now]=true;
            tot++;
        }
        if(tot==x)
        {
            res++;
            for(int i=0;i<x;i++)
                printf(i==x-1?"%d\n":"%d ",a[i]);
        }
        if(!next_permutation(a,a+x)) break;
    }
    printf("%d\n",res);
}
int main()
{
    for(int i=1;i<=10;i++)
        f(i);
}
#include<bits/stdc++.h>
using namespace std;
int n,a[110000];
void solve(){
    cin>>n;
    if(n==1) printf("0");
    else if(n==2) printf("1 0");
    else if(n%2) printf("-1");
    else{
        for(int i=0;i<n/2;i++) printf("%d ",n-1-2*i);
        printf("0 ");
        for(int i=n/2+1;i<n-1;i++) printf("%d ",n-2*(i-n/2));
        printf("2");
    }
 
}
int main(){
    solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值