高松登的比赛复盘 - 7月下月刊

七月下半主要可能就是牛客多校联赛了 虽然开局排位很低但是哥们儿还有一颗打区域赛的心

注:没买看不到题面的话其实直接随便点进一个提交 上面会写description

2024牛客暑期多校训练营1

第一场有点太着急了 没想到牛客的难度梯度这么变态的 上来还准备早点a后面能多做几道的 所以wa了好几发 后来就一直看着所有人一点点超上去 真的好气啊

C - Sum of Suffix Sums

所有后缀和加起来其实对第i个数就一共算了i次 所以直接维护一个sum就可以了

用C写取模处理好麻烦 一直wa 最后直接干脆上python然后只在最后取一次模了

n = int(input())
MOD = 1000000007
lst=[]
sum = 0
for x in range(1,n+1):
    s = input().split()
    u = int(s[0])
    v = int(s[1])
    while u>0:
        u-=1
        sum-= lst[-1]*len(lst)
        lst.pop()
    lst.append(v)
    sum+= lst[-1]*len(lst)
    print(sum%MOD)

H - World Finals

自定义cmp然后sort 重复的可以直接打到另外一场比赛去 我单哈希交了一发双哈希交了一发都wa了 最后直接string开map过了 真的是搞心态

#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
#include <string>
#include <vector>
#include <cctype>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
#define qwq ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

LL read()
{
    LL sum = 0, fl = 1;
    int ch = getchar();
    for (; !isdigit(ch); ch = getchar())
        if (ch == '-')
            fl = -1;
    for (; isdigit(ch); ch = getchar())
        sum = sum * 10 + ch - '0';
    return sum * fl;
}

LL n, m;
const int N = 1e5 + 10;
string myname = "lzr010506";
struct node
{
    string name;
    LL num, time;
    bool operator<(const node &T) const
    {
        if(num!=T.num)
            return num > T.num;
        else
            return time < T.time;
    }

} c1[N], c2[N];
map<string, int> mp1, mp2;

void solve()
{
    cin >> n;
    for (int i = 1; i <= n;i++)
        cin >> c1[i].name >> c1[i].num >> c1[i].time,mp1[c1[i].name]=1;
    cin >> m;
    for (int i = 1; i <= m; i++)
        cin >> c2[i].name >> c2[i].num >> c2[i].time,mp2[c2[i].name]=1;
    sort(c1 + 1, c1 + 1 + n);
    sort(c2 + 1, c2 + 1 + n);

    LL ans = 0;
    for (int i = 1; i <= n;i++)
    {
        if(c1[i].name==myname)
        {
            ans++;
            break;
        }
        else if(mp1[c1[i].name]&&mp2[c1[i].name])
            continue;
        else
            ans++;
    }

    LL cnt = 0;
    for (int i = 1; i <= m; i++)
    {
        if (c2[i].name == myname)
        {
            cnt++;
            break;
        }
        else if (mp1[c2[i].name] && mp2[c2[i].name])
            continue;
        else
            cnt++;
    }

    // for (int i = 1; i <= n;i++)
    //     cout << c1[i].name << endl;
    // cout << endl;
    // for (int i = 1; i <= m; i++)
    //     cout << c2[i].name << endl;

    cout << min(ans, cnt);
}

int main()
{
    qwq;
    solve();
    return 0;
}

A - A Bit Common

考虑在数组中选取k个数的情况 那么这k个数中每一位至少有一个数为1 剩下的n-k个数完全随意 然后对k从1枚举到n即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int n,m,q;
int C[5005][5005];
void init()
{
    for(int i=0;i<=5000;i++)
    {
        C[i][0]=1;
        for(int j=1;j<=i;j++)
        {
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%q;
        }
    }
}
ll qpow(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a%q;
        a=a*a%q;
        b>>=1;
    }
    return res;
}

int main()
{
    scanf("%d%d%d",&n,&m,&q);
    init();
    ll ans=0;
    for(ll k=1;k<=n;k++)
    {
        ans+=C[n][k]%q*qpow(2,(n-k)*(m-1))%q*qpow(qpow(2,k)-1,m-1)%q;
        ans%=q;
    }
    printf("%lld\n",ans);
    return 0;
}

I - Mirror Maze

记忆化搜索 众生平等屎山题 参考小学哥的代码补的题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int N = 1010;

int i, j, k, n, m, t, res, f[N][N][4], ty, flag, sb;
int mp[N][5], dx[N], dy[N];
bool vis[N][N][4], st[N][N];
string s[N];
map<string, int> cmd;
vector<tuple<int, int, int, int> > q;
vector<pair<int, int> > v;

void dfs(int x, int y, int ty)
{
    if (x < 1 || x > n || y < 1 || y > m)
    {
        f[x][y][ty] = 0;
        return;
    }
    if (vis[x][y][ty])
    {
        flag = 1;
        return;
    }
    int nxt = mp[s[x][y]][ty];
    vis[x][y][ty] = 1;
    q.push_back({x, y, ty, ty != nxt});
    int x1 = x + dx[nxt], y1 = y + dy[nxt];
    dfs(x1, y1, nxt);
}

void Do(int x, int y, int ty)
{
    q = {};
    v = {};
    flag = 0;
    if (x < 1 || x > n || y < 1 || y > m)
    {
        f[x][y][ty] = 0;
        return;
    }
    dfs(x, y, ty);
    int tot = 0;
    reverse(q.begin(), q.end());
    if (flag)
    {
        for (auto [x, y, ty, z]: q)
        {
            if (z && !st[x][y])
            {
                st[x][y] = 1;
                tot++;
                v.push_back({x, y});
            }
        }
        for (auto [x, y, ty, z]: q)
        {
            f[x][y][ty] = tot;
        }
    }
    else
    {
        for (auto [x, y, ty, z]: q)
        {
            if (z && !st[x][y])
            {
                st[x][y] = 1;
                tot++;
                v.push_back({x, y});
            }

            f[x][y][ty] = tot;
        }
    }
    for (auto [i, j]: v)
        st[i][j] = 0;
}

void ini()
{
    memset(f, -1, sizeof(f));
    mp['|'][0] = 0;mp['|'][1] = 3;mp['|'][2] = 2;mp['|'][3] = 1;
    mp['-'][0] = 2;mp['-'][1] = 1;mp['-'][2] = 0;mp['-'][3] = 3;
    mp['/'][0] = 1;mp['/'][1] = 0;mp['/'][2] = 3;mp['/'][3] = 2;
    mp['\\'][0] = 3;mp['\\'][1] = 2;mp['\\'][2] = 1;mp['\\'][3] = 0;
    dx[0] = -1;dy[1] = 1;dx[2] = 1;dy[3] = -1;
    cmd["above"] = 0;cmd["right"] = 1;cmd["below"] = 2;cmd["left"] = 3;
}

void solve()
{
    ini();
    scanf("%d%d", &n, &m);
    for (i = 1; i <= n; i++)
    {
        cin >> s[i];
        s[i] = "$" + s[i];
    }
    for (i = 1; i <= n; i++)
    {
        Do(i, 1, 1);
        Do(i, m, 3);
    }
    for (i = 1; i <= m; i++)
    {
        Do(1, i, 2);
        Do(n, i, 0);
    }
    scanf("%d", &t);
    while (t--)
    {
        string s;
        scanf("%d%d", &i, &j);
        cin >> s;
        ty = cmd[s];
        i += dx[ty];
        j += dy[ty];
        if (!vis[i][j][ty])
        {
            Do(i, j, ty);
        }
        printf("%d\n", f[i][j][ty]);
    }
}

int main()
{
    int T = 1;
    //scanf("%d",&T);
    while (T--)
    {
        solve();
    }
    return 0;
}

2024_SCAU暑假组队专题训练1-动态规划专题

一个队的dp低手 就没几道题是dp写出来的 dp场真闹麻了QwQ

不过跟我也没啥关系 我整场摸鱼就a了一道题 甚至打了一把肉鸽(

easier_than_nowcoder

H - Maximum Subarray

谁能想到第一个做出来的是线段树啊喂

哥们儿的贡献只有那个小于零转化的特判

I - Frog 2 

 B - evilboy说这是道签到题

我的思路是克鲁斯卡尔跑一下建图然后从根dp上来就行了 无奈克鲁斯卡尔不会写 会写的在死磕K题 另外一个队友不知道什么算法反正写出来了

C - 不要62 

这题我过的 数位dp 不过哥们直接打表的 反正就1e6 中间甚至因为前缀和下标问题WA了一发(

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=1000010;
string check1="4",check2="62";
int ans[N];
void ini()
{
    memset(ans,0,sizeof(ans));
    for(int i=1;i<N;i++)
    {
        ans[i]=ans[i-1];
        string s=to_string(i);
        int l=s.length();
        if(s.find(check1)<1e9 or s.find(check2)<1e9)
            continue;
        ans[i]++;
    }
}

void solve()
{
    int a,b;
    scanf("%d%d",&a,&b);
    while(a!=0 or b!=0)
    {
        int ret=ans[b]-ans[a-1];
        printf("%d\n",ret);
        scanf("%d%d",&a,&b);
    }
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    ini();
    while(T--)
    {
        solve();
    }
    return 0;
}

J - Independent Set

D - Mowing the Lawn G 

这个dp我赛时居然想对了 就是到第i个小迷弟然后看要不要他分别是0,1 但我不知道具体怎么维护 居然是用堆转化为滑动窗口 学到了学到了 洛谷这篇写的真的可以

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=1e6+5;
int n,k;
ll sum[N];
ll dp[N][2];
deque<int> q;

void solve()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&sum[i]);
        sum[i]+=sum[i-1];
    }
    q.push_back(0);
    for(int i=1;i<=n;i++)
    {
        dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
        while(!q.empty() and q.front()<i-k) 
            q.pop_front();
        dp[i][1]=dp[q.front()][0]+sum[i]-sum[q.front()];
        while(!q.empty() and dp[q.back()][0]-sum[q.back()]<=dp[i][0]-sum[i]) 
            q.pop_back();
        q.push_back(i);
    }
    printf("%lld\n",max(dp[n][0],dp[n][1]));
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

2024牛客暑期多校训练营2 

没买资格的可以点这里看到题目 这场改了下战略 虽然还是只写出三道签到题但是罚时少了很多 顺利挺进前600 而且哥们儿开局血c两题 这把我狠狠带飞了

E - GCD VS XOR

开局过那么快 肯定是打表啦

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    for(int i=1;i<=100;i++)
    {
        printf("x=%d ",i);
        for(int j=i-1;j>=1;j--)
        {
            if(__gcd(i,j)==(i^j))
            {
                printf("y=%d ",j);
            }
        }
        printf("\n");
    }
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

用上面的代码打出来是

x=1
x=2
x=3 y=2
x=4
x=5 y=4
x=6 y=4
x=7 y=6
x=8
x=9 y=8
x=10 y=8
x=11 y=10
x=12 y=8
x=13 y=12
x=14 y=12
x=15 y=14 y=12 y=10
x=16
x=17 y=16
x=18 y=16
x=19 y=18
x=20 y=16
x=21 y=20
x=22 y=20
x=23 y=22
x=24 y=16
x=25 y=24
x=26 y=24
x=27 y=26 y=24 y=18
x=28 y=24
x=29 y=28
x=30 y=28 y=24 y=20
x=31 y=30
x=32
x=33 y=32
x=34 y=32
x=35 y=34
x=36 y=32
x=37 y=36
x=38 y=36
x=39 y=38 y=36
x=40 y=32
x=41 y=40
x=42 y=40
x=43 y=42
x=44 y=40
x=45 y=44 y=40 y=36
x=46 y=44
x=47 y=46
x=48 y=32
x=49 y=48
x=50 y=48
x=51 y=50 y=48 y=34
x=52 y=48
x=53 y=52
x=54 y=52 y=48 y=36
x=55 y=54 y=50
x=56 y=48
x=57 y=56
x=58 y=56
x=59 y=58
x=60 y=56 y=48 y=40
x=61 y=60
x=62 y=60
x=63 y=62 y=60 y=56 y=54 y=42
x=64
x=65 y=64
x=66 y=64
x=67 y=66
x=68 y=64
x=69 y=68
x=70 y=68
x=71 y=70
x=72 y=64
x=73 y=72
x=74 y=72
x=75 y=74 y=72
x=76 y=72
x=77 y=76
x=78 y=76 y=72
x=79 y=78
x=80 y=64
x=81 y=80
x=82 y=80
x=83 y=82
x=84 y=80
x=85 y=84 y=80 y=68
x=86 y=84
x=87 y=86 y=84
x=88 y=80
x=89 y=88
x=90 y=88 y=80 y=72
x=91 y=90
x=92 y=88
x=93 y=92
x=94 y=92
x=95 y=94 y=90 y=76
x=96 y=64
x=97 y=96
x=98 y=96
x=99 y=98 y=96 y=66
x=100 y=96

多看两眼不难发现规律 能除几次2就减去2的多少次方 如果是2的整数次方就是-1

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll qpow(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
            ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}

void solve()
{
    ll x;
    scanf("%lld",&x);
    ll ans=x;
    ll cnt=0;
    while(x%2==0)
    {
        x/=2;
        cnt++;
    }
    ans-=qpow(2,cnt);
    if(ans==0)
        printf("-1\n");
    else
        printf("%lld\n",ans);
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

C - Red Walking on Grid

我们不妨假设这个人只往右边走 因为往左边走的情况一定会有一个往右走的情况完全对应 所以可以直接dp 白色格子肯定是0 红色格子则是右边和下面/上面的最大值+1 然后找到最大值就可以了 注意题目要我求的是步数所以最后要-1

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=1e6+10;
string s[2];
int n;
int dp[2][N];
void solve()
{
    scanf("%d",&n);
    for(int i=0;i<2;i++) cin>>s[i];
    memset(dp,0,sizeof dp);
    int ans=0;
    dp[0][n]=dp[1][n]=0;
    for(int i=n-1;i>=0;i--)
    {
        if(s[0][i]=='R') dp[0][i]=1+dp[0][i+1];
        if(s[1][i]=='R') dp[1][i]=1+dp[1][i+1];
        if(s[0][i]=='R' and s[1][i]=='R')
        {
            int tmp=dp[0][i];
            dp[0][i]=max(dp[0][i],dp[1][i]+1);
            dp[1][i]=max(dp[1][i],tmp+1);
        }
        ans=max(ans,max(dp[0][i],dp[1][i]));
    }
    if(ans>0) ans--;
//    for(int i=0;i<2;i++)
//    {
//        for(int j=0;j<n;j++)
//        {
//            printf("%d ",dp[i][j]);
//        }
//        printf("\n");
//    }
    printf("%d\n",ans);
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

H - Instructions Substring

这题我也贡献了思路嘿嘿 因为只需要经过过(x,y)这个点即可 所以我们不妨直接从头走到尾 记录中间经过的每一个格子 然后从前面删除步骤 那么之前的路径就相当于整体平移了一下 也就相当于终点反向平移了一下 看他有没有落在路径上 在的话后面的点就是可选可不选的状态 对答案进行累加即可

注意对于样例2即要求的终点为(0,0)的情况需要特判

#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
#include <string>
#include <vector>
#include <cctype>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
#define qwq ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

LL read()
{
    LL sum = 0, fl = 1;
    int ch = getchar();
    for (; !isdigit(ch); ch = getchar())
        if (ch == '-')
            fl = -1;
    for (; isdigit(ch); ch = getchar())
        sum = sum * 10 + ch - '0';
    return sum * fl;
}
map<PLL, vector<LL>> mp;
void solve()
{
    LL n, fx, fy;
    cin >> n >> fx >> fy;
    string s;
    cin >> s;
    LL x = 0, y = 0;
    for (int i = 0; i < n; i++)
    {
        mp[{x, y}].push_back(i + 1);
        if (s[i] == 'A')
            x--;
        else if (s[i] == 'D')
            x++;
        else if (s[i] == 'W')
            y++;
        else if (s[i] == 'S')
            y--;
    }

    mp[{x, y}].push_back(n + 1);

    LL ans = 0;
    x = fx, y = fy;
    // printf("bool:%lld\n", mp[{0, 0}].size());
    for (int i = 0; i < n; i++)
    {

        if (mp[{x, y}].size())
            for (LL time : mp[{x, y}])
            {

                if (time >= i + 1)
                {
                    if (time == i + 1)
                        ans += (n + 1) - time;
                    else
                        ans = ans + (n + 1) - time + 1;
                    break;
                }
            }

        if (s[i] == 'A')
            x--;
        else if (s[i] == 'D')
            x++;
        else if (s[i] == 'W')
            y++;
        else if (s[i] == 'S')
            y--;
    }
    printf("%lld\n", ans);
}

int main()
{
    solve();
    return 0;
}

A - Floor Tiles

赛时已经推出来的是全是波浪线的这种情况是线的条数最少的 而ABAB交替填充得到一大堆圆石线的条数最多的

如果k不在这个范围内那么肯定就直接输出No 如果在的话我们就需要考虑如何更换瓷砖来获得更多的线 赛时就觉得这里判断情况太多死活想不出来 赛后经点拨得知每次一定是修改斜对角线的两个可以增加一条线 然后记得只有一行或者一列的时候要进行特判即可通过

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=833;
int n,m,k;
char ans[N][N];
void print()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            printf("%c",ans[i][j]);
        }
        printf("\n");
    }
}

void solve()
{
    scanf("%d%d%d",&n,&m,&k);
    int xiao=n+m;//波浪线的情况
    int da=(n-1)*(m/2)+xiao;//圆的情况
    int ox,oy;
    char oc;
    scanf("%d%d",&ox,&oy);
    cin>>oc;

    memset(ans,oc,sizeof(ans));//先把波浪线画好

    if(n==1 or m==1)//特判一行或者一列的情况
    {
        if(k!=n+m)
        {
            printf("No\n");
            return ;
        }
        printf("Yes\n");
        print();
        return ;
    }
    // 因为我一开始填波浪的时候是一行一行全来就行
    // 可以直接把这个点平移到边边
    int tmp=min(ox,oy);
    ox-=tmp;oy-=tmp;
    ox%=2;oy%=2;
    if(ox>oy)
        swap(ox,oy);
    if(k<xiao or k>da)//在可以找到的范围之外了
    {
        printf("No\n");
        return ;
    }

    //预处理一个值用于决定怎么改
    int u;
    char nc;
    if(oc=='A')
    {
        u=1;nc='B';
    }
    else
    {
        u=0;nc='A';
    }
    if(ox%2==1) u=1-u;
    if(oy%2==u) u=1-u;

    //不断尝试修改
    ll cnt=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(j%2==u)
            {
                ans[i][j]=nc;
                if(i>=1 and j>=1)
                {
                    //必须是这样的形式才能变成圆增多线的条数
                    if(nc=='A' and ans[i-1][j-1]=='A' and ans[i-1][j]=='B' and ans[i][j-1]=='B')
                        cnt++;
                }
                if(i>=1 and j<m-1)
                {
                    if(nc=='B' and ans[i-1][j]=='A' and ans[i-1][j+1]=='B' and ans[i][j+1]=='A')
                        cnt++;
                }
                if(xiao+cnt==k)
                {
                    printf("Yes\n");
                    print();
                    return ;
                }
            }
        }
        u=1-u;
    }
    printf("No\n");
    return ;
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

I - Red Playing Cards

【LGR-194-Div.4】洛谷入门赛 #25 

AK啦!第一次AK 虽然只是洛谷的div4但是好开心

G - respect

从G题开发现也是直接依题意模拟即可 早知道从H开了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    string s;
    cin>>s;
    int n;
    scanf("%d",&n);
    int a[n+5];
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    a[0]=0;
    a[n+1]=s.size();
    int cnt=0;
    for(int i=0;i<=n;i++)
    {
        string tmp;
        for(int j=a[i];j<=a[i+1]-1;j++)
        {
            tmp+=s[j];
        }
//        cout<<tmp<<endl;
        if(tmp.find("respect")<1e8)
            cnt++;
    }
    printf("%d\n",cnt);
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

F - significance

邻接矩阵直接模拟就行 数据小的可怜

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
vector<int> mp[114];

void solve()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        for(int j=0;j<x;j++)
        {
            int y;
            scanf("%d",&y);
            mp[i].push_back(y);
        }
    }
    for(int i=1;i<=n;i++)
    {
        set<int> firends;
        for(auto j:mp[i])
        {
            firends.insert(j);
            for(auto k:mp[j])
            {
                if(k!=i) firends.insert(k);
            }
        }
        printf("%d ",firends.size());
    }
    printf("\n");
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

E - rules

后面一直到A都是依题意模拟即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    int mp[n+1][m+1];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&mp[i][j]);
        }
    }
    int hlf=(n+1)/2;
    int cnt=0;
    for(int i=1;i<=m;i++)
    {
        int nc=0;
        for(int j=1;j<=n;j++)
        {
            if(mp[j][i]==k) nc++;
        }
        if(nc>=hlf)
            cnt++;
    }
    hlf=(m+1)/2;
    if(cnt>=hlf) printf("YES\n");
    else printf("NO\n");
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

D - speech

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    int n,m;
    scanf("%d%d",&n,&m);
    ll beauty[m+1];
    int a[m+1];
    int b[m+1];
    memset(b,0,sizeof(b));
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=0;i<n;i++)
    {
        int x;
        scanf("%d",&x);
        b[x]++;
    }
    int da=0;
    int t=0;
    for(int i=1;i<=m;i++)
    {
        beauty[i]=1ll*a[i]*b[i];
        if(beauty[i]>da)
        {
            da=beauty[i];
            t=i;
        }
    }
    printf("%d\n",t);
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

C - eating

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    int n;
    scanf("%d",&n);
    int ans=0;
    double m=0;
    for(int i=1;i<=n;i++)
    {
        double a,b;
        scanf("%lf%lf",&a,&b);
        if(b/a>m)
        {
            m=b/a;
            ans=i;
        }
    }
    printf("%d\n",ans);
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

A - true

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    int a,b,c;
    scanf("%d%d",&a,&b);
    a/=10;
    b*=10;
    c=10000-a-b;
    printf("%d %d %d\n",a,b,c);
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

B - value

先写的用除法提前算好 但是0的特判太多了 一看数据只有1000那直接遍历搜就完了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    int x,y,z,w;
    scanf("%d%d%d%d",&x,&y,&z,&w);
    for(int c=1;c<=1000;c++)
    {
        if(x==z*c and y==w*c)
        {
            printf("%d\n",c);
            return ;
        }
    }
    printf("-1\n");
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

H - accomplishment

直接找所有3*3的中心累加就行 我当时没看到n和m一定是3的倍数还写了个特判 如果模3是1的话要先吃第一排和最后一排

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int nx=2,ny=2;
    if(n%3==1)
        nx=1;
    if(m%3==1)
        ny=1;
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            ll c;
            scanf("%lld",&c);
            if(i%3==nx and j%3==ny)
                sum+=c;
        }
    }
    printf("%lld\n",sum);
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

I - sql

指令的处理用python的input然后split会方便很多所以直接用python写了

n = int(input())
tables = {}

for _ in range(n):
    table_name = input()
    x, y = map(int, input().split())
    headers = input().split()
    table = []
    for _ in range(x-1):
        row = dict(zip(headers, input().split()))
        table.append(row)
    tables[table_name] = table

m = int(input())
for _ in range(m):
    query = input().split()
    table_name = query[3]
    columns = query[1].split(',')
    header, value = query[5].split('=')
    for row in tables[table_name]:
        if row[header] == value:
            print(' '.join(row[column] for column in columns))

AtCoder Beginner Contest 363

A - Piling Up

依据题意模拟即可

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int main()
{
    int n;
    scanf("%d",&n);
    if(1<=n and n<=99)
        printf("%d\n",100-n);
    else if(n<=199)
        printf("%d\n",200-n);
    else if(n<=299)
        printf("%d\n",300-n);
    else if(n<=399)
        printf("%d\n",400-n);
    else if(n<=499)
        printf("%d\n",500-n);
    else if(n<=599)
        printf("%d\n",600-n);
    else if(n<=699)
        printf("%d\n",700-n);
    else if(n<=799)
        printf("%d\n",800-n);
    else
        printf("%d\n",900-n);
    return 0;
}

B - Japanese Cursed Doll

lower_bound查找即可

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int main()
{
    int n,t,p;
    scanf("%d%d%d",&n,&t,&p);
    int L[n];
    for(int i=0;i<n;i++)
        scanf("%d",&L[i]);
    sort(L,L+n);
    int ans=t-L[n-p];
    if(ans<0)
        ans=0;
    printf("%d\n",ans);
    return 0;
}

C - Avoid K Palindrome 2

依据题意模拟 加到桶里面然后dfs全排列 最后判断

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int n,k;
int ans=0;
string s;
char t[20];
int st[200];
map<string,int> mp;
void check()
{
    if(mp[t]) return ;
//    cout<<t<<endl;
    mp[t]=1;
    for(int i=0;i+k<=n;i++)
    {
        int flag=1;
        for(int j=0;j<k/2;j++)
        {
            if(t[i+j]!=t[i+k-1-j])
            {
                flag=0;
                break;
            }
        }
        if(flag) return ;
    }
    ans++;
//    cout<<"!"<<endl;
}
void dfs(int p)
{
    if(p==n)
    {
        check();
        return ;
    }
    for(int i='a';i<='z';i++)
    {
        if(st[i]>0)
        {
            st[i]--;
            t[p]=(char)i;
            dfs(p+1);
            st[i]++;
        }
    }
}

int main()
{
    scanf("%d%d",&n,&k);
    cin>>s;
    for(char a:s) st[a]++;
    dfs(0);
    printf("%d\n",ans);
    return 0;
}

D - Palindromic Number

求第N个回文数 有板子 虽然数据比较大 修改一下只输出前一半然后后一半用字符串处理

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve(ll index)
{
    ll res,cnt=0,w=0,num=9,half=1;
    while(1)
    {
        if(w>0 and w%2==0){
            num*=10;
        }
        w++;
        if(cnt+num>=index)
            break;
        cnt+=num;
    }
    index=index-cnt-1;
    for(int i=0;i<(w-1)/2;i++)
    {
        half*=10;
    }
    half+=index;
    printf("%lld",half);
    string s=to_string(half);
    if(w%2==0)
    {
        for(int i=s.size()-1;i>=0;i--)
        {
            printf("%c",s[i]);
        }
    }
    else
    {
        for(int i=s.size()-2;i>=0;i--)
        {
            printf("%c",s[i]);
        }
    }
}
int main()
{
    ll n;
    scanf("%lld",&n);
    if(n==1)
    {
        printf("0\n"); // 修改这里,当n为1时,输出0
        return 0;
    }
    n--;
    solve(n);
    return 0;
}

E - Sinking Land

赛时思路对的感觉时间复杂度没敲 赛后敲完立马过了 这次我是真的红温了 跟答案的dfs不太一样 我是直接堆优化强行模拟 一个格子沉默就把他旁边的不在队列里面的格子全部加进优先队列

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef tuple<int,int,int> tii;
struct compare {
    bool operator()(const tuple<int, int, int>& a, const tuple<int, int, int>& b) {
        return get<0>(a) > get<0>(b);
    }
};
priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, compare> pq;

int main()
{
    int h,w,year;
    scanf("%d%d%d",&h,&w,&year);
    int mp[h+5][w+5];
    memset(mp,0,sizeof(mp));
    bool vis[h+5][w+5];
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=h;i++)
    {
        for(int j=1;j<=w;j++)
        {
            scanf("%d",&mp[i][j]);
        }
    }
    for(int i=1;i<=h;i++)
    {
        for(int j=1;j<=w;j++)
        {
            if(mp[i-1][j]==0 or mp[i+1][j]==0 or mp[i][j-1]==0 or mp[i][j+1]==0)
            {
//                printf("%d %d\n",i,j);
                pq.push({mp[i][j], i, j});
                vis[i][j]=true;
            }
        }
    }
    int cnt=0;
    int all=h*w;
    for(int i=1;i<=year;i++)
    {
//        printf("%d\n",get<0>(pq.top()));
        while(get<0>(pq.top())<=i and pq.size()>0)
        {
            int x=get<1>(pq.top()),y=get<2>(pq.top());
            pq.pop();
            if(vis[x-1][y]==false and mp[x-1][y]!=0)
            {
                pq.push({mp[x-1][y], x-1, y});
                vis[x-1][y]=true;
            }
            if(vis[x+1][y]==false and mp[x+1][y]!=0)
            {
                pq.push({mp[x+1][y], x+1, y});
                vis[x+1][y]=true;
            }
            if(vis[x][y-1]==false and mp[x][y-1]!=0)
            {
                pq.push({mp[x][y-1], x, y-1});
                vis[x][y-1]=true;
            }
            if(vis[x][y+1]==false and mp[x][y+1]!=0)
            {
                pq.push({mp[x][y+1], x, y+1});
                vis[x][y+1]=true;
            }
            cnt++;
        }
        printf("%d\n",all-cnt);
    }
    return 0;
}

The 2023 ICPC Asia Jinan Regional Contest (The 2nd Universal Cup. Stage 17: Jinan)

济南省赛 狠狠n+1队长

D - Largest Digit

A - Many Many Heads 

直接计数 连续三个就寄

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    string s;
    cin>>s;
    vector<int> ts(s.length());
    for (int i=0;i<s.length();i++)
    {
        if (s[i]=='(' or s[i]==')')
        {
            ts[i]=1;
        }
        else
        {
            ts[i]=-1;
        }
    }
    int cnt=0;
    for(int i=0;i<s.length()-1;i++)
    {
        if(ts[i]==ts[i+1])
        {
            cnt++;
        }
        if(cnt>=3)
        {
            printf("NO\n");
            return;
        }
    }
    printf("YES\n");
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

I - Strange Sorting

只要遇到不一样的就贪心从后面找能换的 保证一次能换最多

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int a[114];
int n;
void solve()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    vector<pii> ans;
//    printf("???\n");
    for(int i=1;i<=n;i++)
    {
        if(a[i]!=i)
        {
            int j=n;
            for(;j>i;j--) if(a[j]<a[i]) break;
            ans.push_back({i,j});
            sort(a+i,a+j+1);
        }
    }
    printf("%d\n",ans.size());
    for(auto p:ans) printf("%d %d\n",p.first,p.second);
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

K - Rainbow Subarray

补题 今天学会了双set动态维护中位数 好好好 然后这题我们把每个数都减去对应下标就变成了k步使一段序列完全相等 找中位数就用上面说的板子加上滑动窗口维护就行

#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=1e6+10;
const int INF=0x3f;
int n,m;
int q[N];
multiset<int> s1,s2;
bool check(int mid,int a,int b)
{
    int ret=0;
    ret+=a-mid*(int)s2.size();
    ret+=mid*(int)s1.size()-b;
    return ret<=m;
}
int solve()
{
    int ans=1;
    s1.clear();
    s2.clear();
    int mid=q[1];
    int res1=0,res2=0;
    s2.insert(mid);
    res2+=mid;
    for(int i=2,l=1;i<=n;i++)
    {
        if(q[i]>=mid)
        {
            s2.insert(q[i]);
            res2+=q[i];
        }
        else
        {
            s1.insert(q[i]);
            res1+=q[i];
        }
        while(s1.size()+1<s2.size())
        {
            auto t=s2.begin();
            res1+=*t;
            res2-=*t;
            s1.insert(*t);
            s2.erase(t);
        }
        while(s1.size()>s2.size())
        {
            auto t=s1.end();
            t--;
            res1-=*t;
            res2+=*t;
            s2.insert(*t);
            s1.erase(t);
        }
        mid=*s2.begin();
        while(!check(mid,res2,res1))
        {
            auto t=s1.find(q[l]);
            if(t!=s1.end())
            {
                res1-=q[l];
                s1.erase(t);
            }
            else
            {
                res2-=q[l];
                s2.erase(s2.find(q[l]));
            }
            l++;
            while(s1.size()+1<s2.size())
            {
                auto t=s2.begin();
                res1+=*t;
                res2-=*t;
                s1.insert(*t);
                s2.erase(t);
            }
            while(s1.size()>s2.size())
            {
                auto t=s1.end();
                t--;
                res1-=*t;
                res2+=*t;
                s2.insert(*t);
                s1.erase(t);
            }
            mid=*s2.begin();
        }
        ans=max(ans,i-l+1);
    }
    return ans;
}

signed main()
{
    int T=1;
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&q[i]);
            q[i]-=i;
        }
        printf("%lld\n",solve());
    }
    return 0;
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值