中登的比赛复盘 - 7月上月刊

7月份大概率就只参加下学校的暑假个人赛 其他时间要么acwing要么打游戏去了

The 2024 Shanghai Collegiate Programming Contest

上海市赛 体验一般 主要还是菜

E - 无线软件日

开桶计数即可

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
    int n;
    cin>>n;
    string s;
    cin>>s;
    int bl[300]={0};
    for(int i=0;i<n;i++)
    {
        bl[tolower(s[i])]++;
    }
    int ans=1e9;
    ans=min(ans,bl['s']);
    ans=min(ans,bl['h']/2);
    ans=min(ans,bl['a']/2);
    ans=min(ans,bl['n']);
    ans=min(ans,bl['g']);
    ans=min(ans,bl['i']);
    cout<<ans<<endl;
    return 0;
}

J - 极简合数序列

前缀和

#include<bits/stdc++.h>
using namespace std;
const long long N=1050;
const long long mod= 80112002;
map<long long,long long>mp;
long long a[N],qz[N];
bool check(long long x)
{
    for(long long i=2;i<=sqrt(x);i++)
        if(x%i==0)
           return true;
    return false;
}
void solve()
{
    long long i,j,k,tt,h,n,m,ma=0,ans=10000000,sum=0,flag=1;
    cin>>n;
    for(i=1;i<=n;i++)
        {cin>>a[i];qz[i]=qz[i-1]+a[i];}
    for(i=1;i<=n;i++)
    {
        for(j=n;j>=i;j--)
        {
            if(check(qz[j]-qz[i-1]))
               ans=min(ans,j-i);
        }
    }
    if(ans==10000000)
        cout<<-1<<endl;
    else
        cout<<ans<<endl;

}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
	long long t;
    t=1;
    cin>>t;
    while(t--)
        solve();
	return 0;
}

A - 无线网络整点栅格统计

遍历正方形一条边上相邻的两个顶点 用向量旋转的方式即可求出另外两个点的坐标 再判断这些点是不是在范围内

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
int n,m;

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++)
    {
        for(int j=0;j<=m;j++)
        {
            int ans=0;
            for(int x=0;x<=n;x++)
            {
                for(int y=0;y<=m;y++)
                {
                    if(x==i and y==j)
                        continue;
                    int ok=0;
                    int p=(x-(j-y));
                    int q=(y+(i-x));
                    if(0<=p and p<=n and 0<=q and q<=m)
                        ok++;
                    p=(i-(j-y));
                    q=(j+(i-x));
                    if(0<=p and p<=n and 0<=q and q<=m)
                        ok++;
                    if(ok==2)
                        ans++;

                    ok=0;
                    p=(x+(j-y));
                    q=(y-(i-x));
                    if(0<=p and p<=n and 0<=q and q<=m)
                        ok++;
                    p=(i+(j-y));
                    q=(j-(i-x));
                    if(0<=p and p<=n and 0<=q and q<=m)
                        ok++;
                    if(ok==2)
                        ans++;
                }
            }
            printf("%d ",ans/2);
        }
        printf("\n");
    }
    return 0;
}

一开始写的是一个四个方向两两取最小 然后发现还有斜着的 写了一个每三个方向两两取最小再和另一边的一半取最小 发现还是不够 后来才发现还有可能摆出其他角度的正方形

2024 (ICPC) Jiangxi Provincial Contest -- Official Contest

江西省赛 继续和我🐔哥甜蜜双排 这场体验还不错 双人拿铜 要是再有个人我都不敢想

A - Maliang Learning Painting

签到题 a+b+c问题

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
    ll a,b,c;
    cin>>a>>b>>c;
    cout<<a+b+c<<endl;
    return 0;
}

C - Liar

第一眼是个后悔贪心 从小到大塞进去 一不小心塞多了就从前面二分找到合适的点吐出来

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
    int n,s;
    cin>>n>>s;
    int a[n];
    for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n);
    int i=1;
    int my=a[0];
    while(my<=s and i<=n)
    {
        my+=a[i];
        i++;
    }
    i--;
    cout<<i<<endl;
    return 0;
}

结果WA3了 后来快一小时才想起来应该是如果加起来刚好是s那所有人都说的真话 要不然就可以n-1人说的真话 剩下那人根据s的大小自适应即可 反正可正可负 随便给他塞一个上去就行

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
    int n,s;
    cin>>n>>s;
    int a[n];
    int sum=0;
    for(int i=0;i<n;i++)
    {
        cin >> a[i];
        sum+=a[i];
    }
    if(sum==s)
        cout<<n<<endl;
    else
        cout<<n-1<<endl;
    return 0;
}

J - Magic Mahjong

又过了半个小时 🐔哥过了麻将 我因为题目太长而且我没打过所以一眼都没看喵

K - Magic Tree

这题一开始题目一直读不懂 后来发现其实每往后延伸一列就多两种情况 也就是写个qpow就行了

#include <bits/stdc++.h>
#define MOD 998244353
using namespace std;
typedef long long ll;
ll qpow(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
            ans=ans*a%MOD;
        a=a*a%MOD;
        b>>=1;
    }
    return ans;
}

int main()
{
    ll n;
    cin>>n;
    ll ans=qpow(2,n-1);
    cout << ans << endl;
    return 0;
}

G - Multiples of 5

最犯蠢的一集来了 首先我是一位1e14是数字本体的最大大小写了个暴力wa了

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
int n;
ll pow11[19]={1,11,121,1331,14641,161051,1771561,19487171,214358881,2357947691,25937424601,285311670611,3138428376721,34522712143931,379749833583241,4177248169415651,45949729863572161,505447028499293771,5559917313492231481};
ll change(vector<ll> v)
{
    int length=v.size();
    ll ans=0;
    for(int i=0;i<length;i++)
    {
        ans+=v[i]*pow11[length-i-1];
    }
    return ans;
}

int main()
{
    int T=1;
    cin>>T;
    while(T--)
    {
        cin>>n;
        vector<ll> v;
        while(n--)
        {
            char a,b;
            cin>>a>>b;
            int num=b-'0';
            if(b=='A')
                num=11;
            while(a--)
                v.push_back(num);
        }
        ll num=change(v);
        printf("%lld ",num);
        if(num%5==0)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

然后我以为是直接模拟算出来的数字太大会导致爆int 再加上判断一个10进制数是不是5的倍数只需要看个位就行了所以加了个模10 结果还是wa

虽然上面很蠢 但是奠定了我们做出这道题的基础 然后就发现11的任意次方的结果的个位都是1 那就不需要考虑了 直接a*b就行了 这个时候脑子又抽一下 因为b是可能是A所以要用char存 但是 我把a也用char存了 于是喜提一发tle 人还懵呢 怎么暴力不tle这个反而tle了 这个时候我们J题还没写出来 然后JK写出来之后队友马上快重构出来的时候我盯着代码看出来了 改完交一发抢先一步过了成功让队友白写10分钟(

不过不能让我们🐔哥白写 还是贴他的代码吧

#include<bits/stdc++.h>
using namespace std;
const long long N=1050;
const long long mod= 80112002;
long long a[N],qz[N];
vector<long long>g[N];
map<char,long long>mp;
void solve()
{
    long long i,j,k,n,m,ma=0,ans=0,sum=0,flag=1;
    cin>>n;
    char kk;
    for(i=1;i<=n;i++)
    {
        cin>>k>>kk;
        if(kk=='A')
            //ans+=k*2;
            continue;
        else
            ans+=k*(kk-'0');
        ans%=10;
    }
    //cout<<ans<<endl;
    if(ans%5)
        cout<<"No"<<endl;
    else
        cout<<"Yes"<<endl;

}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
	long long t;
    t=1;
    cin>>t;
    while(t--)
        solve();
	return 0;
}

H - Convolution

这题也是题目超级无敌长 最后看过题数好多 而且就差这题上铜了才决定看的 题意是对于每个位置 他在新矩阵的值是以他为左上角框一个k那么大的矩阵 然后对应位置乘起来然后加在一起

题目只要我们去找总和 所以我们考虑k矩阵中每个数对答案的贡献 很容易看出就是自己乘上除去右边和下面对饮距离的所有值的和 为了让答案最大 如果这个和是正数我就给k正数 如果是负数我就给负数把他变成正的 具体操作的时候用一下二位前缀和就OK了

#include<bits/stdc++.h>
using namespace std;
const long long N=1050;
const long long mod= 80112002;
long long a[N][N],qz[N][N],qq[N];
vector<long long>g[N];
map<char,long long>mp;
void solve()
{
    long long i,j,k,n,m,l,ma=0,ans=0,sum=0,x,y,p,q;
    cin>>n>>m>>k>>l;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            cin>>a[i][j];
            qq[j]=qq[j-1]+a[i][j];
            qz[i][j]=qz[i-1][j]+qq[j];
            //cout<<qz[i][j]<<' ';
        }
       // cout<<endl;
    }
    /*
   cout<<endl;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            cout<<qz[i][j]<<' ';
        }
        cout<<endl;
    }
    cout<<endl;*/
    p=n-k+1;
    q=m-l+1;




    for(x=p;x<=n;x++)
    {
       for(y=q;y<=m;y++)
        {
            //ans+=(abs(qz[n+x-k][m+y-1]+qz[x-1][y-1]-qz[n+x-k][y-1]-qz[x-1][m+y-1]));
            //cout<<abs(qz[n+x-k][m+y-1]+qz[x-1][y-1]-qz[n+x-k][y-1]-qz[x-1][m+y-1])<<' ';
             ans+=(abs(qz[x][y]+qz[x-p][y-q]-qz[x-p][y]-qz[x][y-q]));

        }
        //cout<<endl;
    }
   // cout<<endl;
    cout<<ans;




    /*
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            cout<<qz[i][j]<<' ';
        }
        cout<<endl;
    }
*/

}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
	long long t;
    t=1;
    //cin>>t;
    while(t--)
        solve();
	return 0;
}

牛客练习赛127

上个月一直以为牛客很简单的我昨晚练习赛瞬间老实了 一题耻辱下播 主要是下午大数操作写出阴影了真的不想写了

A - 小红的最大价值

A题甚至还打反符号wa了一发 真破防了 不打了 掉就掉吧

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    int a[n];
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    sort(a,a+n);
    if(a[0]+k>=a[n-1])
        printf("%d\n",a[n-2]);
    else
        printf("%d\n",a[n-1]);
    return 0;
}

Denso Create Programming Contest 2024(AtCoder Beginner Contest 361)

D题写dfs剪枝搞半天后来看题解才知道是bfs E题搞dij搞半天后来才发现是棵树 F题有数学结论 所以最后三题耻辱下播 不过还是稳稳上分中喵

A - Insert 

依据题意模拟即可

#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,k,x;
    cin >> n>>k>>x;
    int a[n+1];
    for (int i = 1; i <= n; i++) cin >> a[i];
    for(int i=1;i<=n;i++)
    {
        cout<<a[i]<<" ";
        if(i==k)
        {
            cout<<x<<" ";
        }
    }
    cout<<"\n";
    return 0;
}

C - Make Them Narrow

排序然后遍历扫一遍找就行 双指针不知道为啥没过wa了一发

#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,k;
    cin >> n >> k;
    int lft=n-k;
    vector<int> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    sort(a.begin(),a.end());
    int ans=1e9;
    for(int i=0;i+lft-1<n;i++)
    {
        ans=min(ans,a[i+lft-1]-a[i]);
    }
    cout << ans << endl;
    return 0;
}

B - Intersection of Cuboids

写完C题之后才想明白的 只需要看三个维度区间相不相交就行

#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 a,b,c,d,e,f,g,h,i,j,k,l;
    cin>>a>>b>>c>>d>>e>>f>>g>>h>>i>>j>>k>>l;
    int cnt=0;
    if((a<=g and g<d)or(g<=a and a<j))
        cnt++;
    if((b<=h and h<e)or(h<=b and b<k))
        cnt++;
    if((c<=i and i<f)or(i<=c and c<l))
        cnt++;
    if(cnt==3)
        cout<<"Yes\n";
    else
        cout<<"No\n";
    return 0;
}

Codeforces Round #956 (Div. 2) and ByteRace 2024

快乐上大分

Codeforces Round 956 (Div. 2)

A - Array Divisibility

先按题意模拟了一下写了个n³发现输出的事1,2,3,4,5那就直接改成输出这个了

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
int n;

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            printf("%d ",i);
        }
        printf("\n");
    }
    return 0;
}

C - Have Your Cake and Eat It Too

b题一开始规律没瞪出来先看C题去了 就是abc的全排列 用前缀和加二分查找 看有没有满足题意的排列 有就输出 没有就-1

#include <bits/stdc++.h>
#define N 200010
using namespace std;
typedef long long ll;
int n;
ll a[N],b[N],c[N];
ll as[N],bs[N],cs[N];
void solve()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld", &a[i]);
        as[i]=as[i-1]+a[i];
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%lld", &b[i]);
        bs[i]=bs[i-1]+b[i];
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%lld", &c[i]);
        cs[i]=cs[i-1]+c[i];
    }
    ll tot=as[n];
    ll cmp=tot/3;
    if(tot%3!=0)
        cmp++;
    int la,ra,lb,rb,lc,rc;

    la=1;
    ra=lower_bound(as+1,as+n+1,cmp)-as;
    lb=ra+1;
    ll lft=bs[ra]+cmp;
    rb=lower_bound(bs+1,bs+n+1,lft)-bs;
    lc=rb+1;
    rc=n;
    if(cs[rc]-cs[lc-1]>=cmp and rb!=-1 and rb<=n and ra!=-1 and ra<=n)
    {
        printf("%d %d %d %d %d %d\n",la,ra,lb,rb,lc,rc);
        return ;
    }

    lb=1;
    rb=lower_bound(bs+1,bs+n+1,cmp)-bs;
    lc=rb+1;
    lft=cs[rb]+cmp;
    rc=lower_bound(cs+1,cs+n+1,lft)-cs;
    la=rc+1;
    ra=n;
    if(as[ra]-as[la-1]>=cmp and rc!=-1 and rc<=n and rb!=-1 and rb<=n)
    {
        printf("%d %d %d %d %d %d\n",la,ra,lb,rb,lc,rc);
        return ;
    }

    lb=1;
    rb=lower_bound(bs+1,bs+n+1,cmp)-bs;
    la=rb+1;
    lft=as[rb]+cmp;
    ra=lower_bound(as+1,as+n+1,lft)-as;
    lc=ra+1;
    rc=n;
    if(cs[rc]-cs[lc-1]>=cmp and ra!=-1 and ra<=n and rb!=-1 and rb<=n)
    {
        printf("%d %d %d %d %d %d\n",la,ra,lb,rb,lc,rc);
        return ;
    }

    la=1;
    ra=lower_bound(as+1,as+n+1,cmp)-as;
    lc=ra+1;
    lft=cs[ra]+cmp;
    rc=lower_bound(cs+1,cs+n+1,lft)-cs;
    lb=rc+1;
    rb=n;
    if(bs[rb]-bs[lb-1]>=cmp and rc!=-1 and rc<=n and ra!=-1 and ra<=n)
    {
        printf("%d %d %d %d %d %d\n",la,ra,lb,rb,lc,rc);
        return ;
    }

    lc=1;
    rc=lower_bound(cs+1,cs+n+1,cmp)-cs;
    lb=rc+1;
    lft=bs[rc]+cmp;
    rb=lower_bound(bs+1,bs+n+1,lft)-bs;
    la=rb+1;
    ra=n;
    if(as[ra]-as[la-1]>=cmp and rb!=-1 and rb<=n and rc!=-1 and rc<=n)
    {
        printf("%d %d %d %d %d %d\n",la,ra,lb,rb,lc,rc);
        return ;
    }

    lc=1;
    rc=lower_bound(cs+1,cs+n+1,cmp)-cs;
    la=rc+1;
    lft=as[rc]+cmp;
    ra=lower_bound(as+1,as+n+1,lft)-as;
    lb=ra+1;
    rb=n;
    if(bs[rb]-bs[lb-1]>=cmp and ra!=-1 and ra<=n and rc!=-1 and rc<=n)
    {
        printf("%d %d %d %d %d %d\n",la,ra,lb,rb,lc,rc);
        return ;
    }

    printf("-1\n");
}

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

B - Corner Twist

做完C题突然豁然开朗 规律就是每一行每一列加起来模3答案都相等就OK了

#include <bits/stdc++.h>
#define N 510
#define M 510
using namespace std;
typedef long long ll;
int n,m;
char a[N][M],b[N][M];

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%s",a[i]);
        for(int i=0;i<n;i++)
            scanf("%s",b[i]);
        int flag=1;
        for(int i=0;i<n;i++)
        {
            int sa=0,sb=0;
            for(int j=0;j<m;j++)
            {
                sa+=a[i][j]-'0';
                sb+=b[i][j]-'0';
            }
            if(sa%3!=sb%3)
            {
                flag=0;
                break;
            }
        }
        if(flag==0)
        {
            printf("No\n");
            continue;
        }
        for(int j=0;j<m;j++)
        {
            int sa=0,sb=0;
            for(int i=0;i<n;i++)
            {
                sa+=a[i][j]-'0';
                sb+=b[i][j]-'0';
            }
            if(sa%3!=sb%3)
            {
                flag=0;
                break;
            }
        }
        if(flag)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

2024_SCAU暑期个人排位赛1

学校暑训首场比赛惨遭倒七😭😭😭 狠狠补题加大班

B - Sand Castle城堡

贪心 两个数组都排列一下然后照题意加加减减就行

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <utility>
#include <cstdio>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=1000010;
int m[N],b[N];

void solve()
{
    int n,x,y;
    scanf("%d%d%d",&n,&x,&y);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&m[i],&b[i]);
    }
    sort(m,m+n);
    sort(b,b+n);
    ll ans=0;
    for(int i=0;i<n;i++)
    {
        if(m[i]<b[i])
            ans+=x*(b[i]-m[i]);
        else if(m[i]>b[i])
            ans+=y*(m[i]-b[i]);
    }
    printf("%lld\n",ans);
}

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

I - Yet Another Card Deck

每张牌其实只有第一个有用 因为把他挪完为止他还是第一个 所以开一个桶记录每张牌第一次出现的位置 然后后续更新每次都是50

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <utility>
#include <cstdio>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int bl[100];

void solve()
{
    int n,q;
    scanf("%d%d",&n,&q);
    memset(bl,0x3f,sizeof(bl));
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        bl[x]=min(bl[x],i);
    }
    int qu[q+1];
    for(int i=1;i<=q;i++)
        scanf("%d",&qu[i]);
    for(int i=1;i<=q;i++)
    {
        int org=bl[qu[i]];
        printf("%d ",org);
        for(int j=1;j<=50;j++)
        {
            if(bl[j]<org)
                bl[j]++;
        }
        bl[qu[i]]=1;
    }
}

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

H - 密码箱

简单把公式逆转一下就得到了x²=qn+1 遍历n的系数q就是根号n的复杂度了 盯着这个代码看了一个小时自暴自弃交的 结果居然过了 真的是...

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <utility>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    ll n;
    scanf("%lld",&n);
    ll q=0;
    ll now=q*n+1;
    ll hlf=sqrt(now);
    while(hlf<=n)
    {
        if(hlf*hlf==now)
            printf("%lld\n",hlf);
        q++;
        now=q*n+1;
        hlf=sqrt(now);
    }
}

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

E - Plate Game

赛时一直在考虑从已知的情况加判断 就是对按顺序摆的情况两边的余数去进行处理 因为两方都可以通过移动几格位置使得场上之后可能的最多的盘子个数减少 甚至一度有想过dp 反正顺序结构一直wa8 就是那种给你希望但是又调不出来的感觉

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <utility>
#include <cstdio>
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%d",&a,&b,&c);
    if(a<c*2 or b<c*2)
    {
        printf("Second\n");
        return ;
    }
    int cnt=(a/(c*2))*(b/(c*2));
    if(a%(c*2)<c)
        cnt--;
    if(b%(c*2)<c)
        cnt--;
    if(cnt%2==1)
        printf("Second\n");
    else
        printf("First\n");
}

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

赛后看了一眼洛谷的题解 现在懂了 先手放中间 然后不管对面放什么都放对称位置 只要第一个盘子能放的下去就一定能赢 赛时过题人数很多 不过听说蛮多guess的 反正我最后叫了十几发各种guess没guess出来喵 居然没有guess到这个最简单的方法

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        int a,b,r;
        scanf("%d%d%d",&a,&b,&r);
        if(a>=2*r and b>=2*r)
            printf("First\n");
        else
            printf("Second\n");
    }
    return 0;
}

F - 序列

赛时用vector模拟的 真的抓破头都想不通为什么不对 特别是赛后一问 旁边的🐔哥就是用set一样的思路写的 更搞不懂了

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <utility>
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);
    vector<ll> v;
    ll ans=0;
    for(int i=0;i<n;i++)
    {
        ll x;
        scanf("%d",&x);
        if(i==0){
            ans+=x;
            v.push_back(x);
        }
        else
        {
            int p=lower_bound(v.begin(),v.end(),x)-v.begin();
            ll add=0x3f;
            if(p<i)
                add=min(add,abs(x-v[p]));
            if(p>0)
                add=min(add,abs(x-v[p-1]));
            ans+=add;
            v.insert(v.begin()+p,x);
        }
    }
    printf("%lld\n",ans);
}

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

题解上说的那个两边找我也试了 也是死活过不了 真的气疯了woc

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <utility>
#include <cstdio>
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);
    vector<pll> v;
    for(int i=1;i<=n;i++)
    {
        ll x;
        scanf("%lld",&x);
        v.push_back({x,i});
    }
    sort(v.begin(),v.end());
    ll ans=0;
    for(int i=0;i<n;i++)
    {
        pll now=v[i];
        if(now.second==1)
        {
            ans+=now.first;
            continue;
        }
        int l=i-1,r=i+1;
        while(l>0 and v[l].second>=now.second)
            l--;
        while(r<n-1 and v[r].second>=now.second)
            r++;
        ans+=min(abs(now.first-v[l].first),abs(now.first-v[r].first));
        //printf("%lld ",ans);
    }
    printf("%lld\n",ans);
}

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

现在再写一遍过了

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
bool st[65540];

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        memset(st,0,sizeof(st));
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            if(i==1)
                ans+=x;
            else
            {
                for(int j=0;j<=65536;j++)
                {
                    if(x+j<=65536 and st[x+j])
                    {
                        ans+=j;
                        break;
                    }
                    if(x-j>=0 and st[x-j])
                    {
                        ans+=j;
                        break;
                    }
                }
            }
            st[x]=true;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

J - 电话网络

赛时的思路是类似spfa算法 开优先队列然后一个一个pop 时间复杂度不对过不了

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <utility>
#include <cstdio>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=10010;
vector<int> v[N];
int cnt[N];
bool cmp(int a,int b)
{
    return cnt[a]>cnt[b];
}

void solve()
{
    int n;
    memset(cnt,0,sizeof(cnt));
    scanf("%d",&n);
    vector<int> q;
    for(int i=1;i<n;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        cnt[a]++;
        cnt[b]++;
        v[a].push_back(b);
        v[b].push_back(a);
        q.push_back(i);
    }
    q.push_back(n);
    int ans=0;
    sort(q.begin(),q.end(),cmp);
    while(cnt[q.front()]!=0)
    {
        int now=q.front();
        ans+=cnt[now];
        cnt[now]=0;
        int l=v[now].size();
        for(int i=0;i<l;i++)
        {
            cnt[v[now][i]]-=2;
        }
        sort(q.begin(),q.end());
    }
    printf("%d\n",ans);
}

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

看了下题解 现在知道是树状dp了 二维dp[i][j]表示第i个点的三种情况 分别是该点建了基站 该点子节点建了基站或是都没建基站 赛时其实有往树那边想但是确实没想树状dp

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N=200010;
int e[N],ne[N],h[N],idx,n;
int dp[N][3];
void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

void dfs(int u,int o)
{
    dp[u][0]=1;
    dp[u][1]=0x3f;
    dp[u][2]=1;
    for(int i=h[u];~i;i=ne[i])
    {
        int j=e[i];
        if(j==o)
            continue;
        dfs(j,u);
        dp[u][0]+=min(dp[j][1],dp[j][2]);
        dp[u][2]+=min(dp[j][1],min(dp[j][0],dp[j][2]));
    }
    for(int i=h[u];~i;i=ne[i])
    {
        int j=e[i];
        if(j==o)
            continue;
        dp[u][1]=min(dp[u][1],dp[u][0]-min(dp[j][1],dp[j][2])+dp[j][2]);
    }
}

int main()
{
    memset(h,-1,sizeof h);
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
    }
    dfs(1,-1);
    printf("%d\n",min(dp[1][1],dp[1][2]));
    return 0;
}

K - 教主的魔法

分块模拟 边补边学 其实就是多存一大堆东西打lazytag嘛

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

#define ll long long
using namespace std;

int n, m, blo;
int v[1000005], bl[1000005], atag[1000005];
vector<int> ve[10001];

ll read()
{
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

void reset(int x)
{
    ve[x].clear();
    for (int i = (x - 1) * blo + 1; i <= min(x * blo, n); i++)
        ve[x].push_back(v[i]);
    sort(ve[x].begin(), ve[x].end());
}

void add(int a, int b, int c)
{
    for (int i = a; i <= min(bl[a] * blo, b); i++)
        v[i] += c;
    reset(bl[a]);
    if (bl[a] != bl[b])
    {
        for (int i = (bl[b] - 1) * blo + 1; i <= b; i++)
            v[i] += c;
        reset(bl[b]);
    }
    for (int i = bl[a] + 1; i <= bl[b] - 1; i++)
        atag[i] += c;
}

int query(int a, int b, int c)
{
    int ans = 0;
    for (int i = a; i <= min(bl[a] * blo, b); i++)
        if (v[i] + atag[bl[a]] < c)
            ans++;
    if (bl[a] != bl[b])
    {
        for (int i = (bl[b] - 1) * blo + 1; i <= b; i++)
            if (v[i] + atag[bl[b]] < c)
                ans++;
    }
    for (int i = bl[a] + 1; i <= bl[b] - 1; i++)
    {
        int x = c - atag[i];
        ans += lower_bound(ve[i].begin(), ve[i].end(), x) - ve[i].begin();
    }
    return ans;
}

int main()
{
    n = read();
    m = read();
    blo = sqrt(n);
    for (int i = 1; i <= n; i++)
        v[i] = read();
    for (int i = 1; i <= n; i++)
        bl[i] = (i - 1) / blo + 1, ve[bl[i]].push_back(v[i]);
    for (int i = 1; i <= bl[n]; i++)
        sort(ve[i].begin(), ve[i].end());
    for (int i = 1; i <= m; i++)
    {
        char f;
        cin >> f;
        int a = read(), b = read(), c = read();
        if (f == 'M')
            add(a, b, c);
        if (f == 'A')
            printf("%d\n", b - a + 1 - query(a, b, c));
    }
    return 0;
}

2024_SCAU暑期个人排位赛2

F - Little Artem and Grasshopper

一旦出界就说明有限 一旦走到走过的格子就说明无限循环

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#define int long long
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("%lld",&n);
    string s;
    cin>>s;
    int a[n];
    bool st[n];
    for(int i=0;i<n;i++)
    {
        scanf("%lld",&a[i]);
        st[i]=false;
    }
    int now=0;
    while(now>=0 and now<n)
    {
        if(st[now])
        {
            printf("INFINITE\n");
            return ;
        }
        st[now]=true;
        if(s[now]=='>')
        {
            now+=a[now];
        }
        else
        {
            now-=a[now];
        }
    }
    printf("FINITE\n");
    return ;
}

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

H - Alice and Bob

一开始想的是一定可以列完1~max(a)的所有值WA了 后来举了个反例2,4,6 特判全是偶数也WA了 发现还有3,6,9等情况 那就是求所有数的gcd

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
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 m=0;
    int pre;
    for(int i=0;i<n;i++)
    {
        int x;
        scanf("%d",&x);
        m=max(m,x);
        if(i==0)
            pre=x;
        else
            pre=__gcd(pre,x);
    }
    m/=pre;
    int cmd=m-n;
    if(cmd%2==0)
        printf("Bob\n");
    else
        printf("Alice\n");
}

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

E - Sorting by Subsequences

把原数字离散化一下就变成了求联通块 dfs并查集都可以

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=100010;
bool st[N];
bool go_back(pii a,pii b)
{
    return a.second<b.second;
}
int ans[N];
int org[N];
vector<pii> all(N);

void solve()
{
    int n;
    scanf("%d",&n);
    memset(st,false,sizeof(st));
    all.push_back({0,0});
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        all[i]={x,i};
    }
    sort(all.begin()+1,all.begin()+n+1);
    for(int i=1;i<=n;i++)
    {
        org[all[i].second]=i;
    }
    int cnt=0;
    for(int i=1;i<=n;i++)
    {
        if(st[i]) continue;
        int j=i;
        while(!st[j])
        {
            st[j]=true;
            j=org[j];
        }
        cnt++;
    }
    printf("%d\n",cnt);
    memset(st,false,sizeof(st));
    ans[0]=0;
    for(int i=1;i<=n;i++)
    {
        if(st[i]) continue;
        int j=i;
        ans[0]=0;
        int idx=1;
        while(!st[j])
        {
            //printf("%d ",j);
            ans[idx]=j;
            idx++;
            ans[0]++;
            st[j]=true;
            j=org[j];
        }
        sort(ans+1,ans+idx);
        for(int i=0;i<idx;i++)
            printf("%d ",ans[i]);
        printf("\n");
    }
}

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

D - Constellation

赛时没有特判垂直的情况一直wa50 100个test太恶心了吧

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<db,db> pii;
typedef pair<ll,ll> pll;
const int N=1000010;
db dis(pii a,pii b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool same(pii a,pii b,pii c)
{
    //特判斜率不存在的情况
    if(a.y==b.y or a.y==c.y or b.y==c.y)
        return a.y==b.y and a.y==c.y and b.y==c.y;
    return fabs((a.x-b.x)/(a.y-b.y)-(a.x-c.x)/(a.y-c.y))<=0.000000001;
}
pii a[N],now[3];
int n,ans[3],p=0;
db m=-88;

void solve()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf",&a[i].x,&a[i].y);
    }
    ans[0]=1;
    now[0]=a[ans[0]];
    for(int i=1;i<=n;i++)
    {
        if(ans[0]==i) continue;
        db dn=dis(now[0],a[i]);
        if(dn<0) continue;
        if(dn<m or m+88.0<=0.0000001)
        {
            m=dn;
            p=i;
        }
    }
    now[1]=a[p];
    ans[1]=p;
    m=-88;
    p=0;
    for(int i=1;i<=n;i++)
    {
        if(i==ans[0] or i==ans[1]) continue;
        if(same(now[0],now[1],a[i])) continue;
        db dn=dis(now[0],a[i])+dis(now[1],a[i]);
        if(dn<0) continue;
        if(dn<m or m+88.0<=0.0000001)
        {
            m=dn;
            p=i;
        }
    }
    now[2]=a[p];
    ans[2]=p;
    for(int i=0;i<3;i++)
        printf("%d ",ans[i]);
    printf("\n");
}

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

A - Elections

逆向贪心 枚举自己最终得票数是多少 然后比他大的全部吃掉 还不够就继续吃最便宜的

赛时一直在想dp 结果看了题解才知道真的是贪心啊woc 没想过这么贪 学习辽

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N=4080;
struct person{
    int p,c;
}s[3005];

bool cmp(person a,person b)
{
    return a.c<b.c;
}

int n,m;
long long ans;
int p[3005];
bool v[3005];

void solve()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&s[i].p,&s[i].c);
        p[s[i].p]++;
    }

    int mv=p[1];
    sort(s+1,s+n+1,cmp);
    int t[3005];
    long long cnt,vote;
    ans=0x7fffffffffffffff;
    for(int i=mv;i<=n;i++){
        memset(v,0,sizeof(v));
        memset(t,0,sizeof(t));
        cnt=vote=0;
        for(int j=1;j<=n;j++){
            if(s[j].p==1){
                vote++,v[j]=1;
                continue;
            }
            if(p[s[j].p]-t[s[j].p]>=i){
                cnt+=s[j].c,v[j]=1,t[s[j].p]++,vote++;
            }
        }
        int j=1;
        while(vote<i){
            if(!v[j])cnt+=s[j].c,vote++;
            j++;
        }
        ans=min(ans,cnt);
    }
    printf("%lld\n",ans);
}

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

2024_SCAU暑期个人排位赛3

洛谷最灵的一集 终于打出一把像样的排位赛了 听洛谷的 晚上div3就不上号了

G - Yet Another String Game

从左往右处理 一个变小一个变大 如果本来是a和z需要特判 可恶的jiejiejiang抢我首杀

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
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 len=s.length();
    for(int i=0;i<len;i++)
    {
        if(i%2==0)
        {
            if(s[i]!='a')
                s[i]='a';
            else
                s[i]='b';
        }
        else
        {
            if(s[i]!='z')
                s[i]='z';
            else
                s[i]='y';
        }
    }
    cout<<s<<endl;
}

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

I - Guess the Array

先问a1+a2,再问a2+a3就可以知道a3-a1,再问a3+a1,解二元一次方程组得a1和a3,然后a2也知道了 之后就从a3+a4一直问到最后就可以了 可恶的ccisdog抢我...算了 榜一大哥还是强啊

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
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);
    int ans[n+1];
    int x,y,z;
    printf("? 1 2\n");
    fflush(stdout);
    scanf("%d",&x);
    printf("? 2 3\n");
    fflush(stdout);
    scanf("%d",&y);
    printf("? 1 3\n");
    fflush(stdout);
    scanf("%d",&z);
    ans[3]=(y-x+z)/2;
    ans[2]=y-ans[3];
    ans[1]=x-ans[2];
    int in;
    for(int i=4;i<=n;i++)
    {
        printf("? %d %d\n",i-1,i);
        fflush(stdout);
        scanf("%d",&in);
        ans[i]=in-ans[i-1];
    }
    printf("! ");
    for(int i=1;i<=n;i++)
    {
        printf("%d ",ans[i]);
    }
    printf("\n");
    fflush(stdout);
    return 0;
}

A - Diamond Miner

就把所有矿工的y值的平方放一起 所有钻石的x的平方放一起 排序之后依次相加开根号就行

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
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);
    vector<db> miner;
    vector<db> mine;
    for(int i=0;i<2*n;i++)
    {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        if(a==0)
        {
            miner.push_back(b*b);
        }
        else if(b==0)
        {
            mine.push_back(a*a);
        }
    }
    sort(mine.begin(),mine.end());
    sort(miner.begin(),miner.end());
    db ans=0;
    for(int i=0;i<n;i++)
    {
        ans+=sqrt(mine[i]+miner[i]);
    }
    printf("%.16lf\n",ans);
}

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

D - Useful Decomposition

就找度大于2的点 如果有很多个那说明不成立 只有一个就对他dfs 注意单链要特判

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=100010;
vector<int> mp[N];
int n;
void dfs(int y,int x)
{
    if(mp[x].size()==1)
    {
        printf("%d",x);
        return ;
    }
    if(mp[x][0]==y)
        dfs(x,mp[x][1]);
    else
        dfs(x,mp[x][0]);
}

void solve()
{
    scanf("%d",&n);
    int cnt=0;
    int t=-1;
    for(int i=1;i<n;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        mp[a].push_back(b);
        mp[b].push_back(a);
        if(mp[a].size()>2 and t!=a)
        {
            cnt++;
            t=a;
        }
        if(mp[b].size()>2 and t!=b)
        {
            cnt++;
            t=b;
        }
    }
    if(cnt>1)
    {
        printf("No\n");
        return ;
    }
    if(t==-1)
    {
        printf("Yes\n1\n");
        for(int i=1;i<=n;i++)
        {
            if(mp[i].size()==1)
                printf("%d ",i);
        }
        printf("\n");
        return ;
    }
    printf("Yes\n%d\n",mp[t].size());
    for(int i:mp[t])
    {
        printf("%d ",t);
        dfs(t,i);
        printf("\n");
    }
}

int main()
{
    int T=1;
    //scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}
//没有大小写啊啊啊啊啊气死我了

C - Moving Pebbles

全场最气人的博弈题 关键是开题特别早 结果到最后就十几个人过

简单来说就是要计数 因为每个数带来的能造成改变的影响不同

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <string>
#include <cstdlib>
#include <ctime>

using namespace std;
typedef long long ll;

int main()
{
    int n;
    scanf("%d", &n);
    int a[n+1];
    map<int,int> st;
    int x=0,y=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        st[a[i]]++;
        if(st[a[i]]%2)
        {
            x++;
            y--;
        }
        else
        {
            y++;
            x--;
        }
    }
    if(!x)
        printf("second player\n");
    else
        printf("first player\n");
    return 0;
}

E - Maximum Value

短到让所有人都觉得可以轻松拿捏的题 最后是罚时刺客 被狠狠拷打了

看了下题解 居然真的是二分 不过和我想象中有点小出入 他是从小到大对每个数往上不停加加 每次二分找范围内最大的数 更新模长

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
    int n;
    int a[1000010];
    int ans=0;
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    int len=unique(a+1,a+n+1)-a-1;
    for(int i=1;i<=len;++i){
        for(int j=a[i];j<=a[len];j+=a[i]){
            int pos=lower_bound(a+1,a+len+1,j+a[i])-a-1;
            ans=max(ans,a[pos]%a[i]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

L - Baby Ehab Partitions Again

看了眼题解 发现我的思路居然是对的啊啊啊啊啊 早知道最后一个小时不扫雷了 主要是中间那个背包判断要写好长 我又懒又觉得复杂度好像不太对就没写 当时觉得那个除2最坏情况会很耗时间 因为我写的是个递归 每次都进行整体操作 题解里面操作部分 总之现在就是非常后悔啊啊啊啊啊

简单讲一下思路 就是如果数组累加和是奇数那必不可能拆 如果是偶数那就减去一个奇数 如果里面没有奇数就全体除2直到出现奇数

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
int a[200];
bool st[200010];

int main()
{
    int n;
    scanf("%d",&n);
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    if(sum%2==1)
    {
        printf("0\n");
        return 0;
    }
    sum/=2;
    st[0]=true;
    for(int i=1;i<=n;i++)
    {
        for(int j=sum;j>=a[i];j--)
        {
            st[j]|=st[j-a[i]];
        }
    }//简单开个背包
    if(!st[sum])
    {
        printf("0\n");
        return 0;
    }
    int minc=1e5,minp=0;
    for(int i=1;i<=n;i++)
    {
        int x=a[i],cnt=0;
        while(!(x&1))
        {
            x>>=1;
            cnt++;
        }
        if(cnt<minc)
        {
            minc = cnt;
            minp = i;
        }
    }
    printf("1\n%d",minp);
    return 0;
}

Codeforces Round 957 (Div. 3)

不上号≠不打 简单补一手题

C - Gorilla and Permutation

让f之和最大就要让左边更早出现更大的有效值 让g最小也就是让右边更迟出现更大的有效值 中间随便排列 简单构造一下就可以了

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
int n,m,k;
int ans[100010];
void solve()
{
    scanf("%d%d%d",&n,&m,&k);
    int ma=n;
    int i=1;
    int tmp=m+1;
    while(ma>=k)
    {
        ans[i]=ma;
        i++;
        ma--;
    }
    int j=n;
    while(m>=1)
    {
        ans[j]=m;
        j--;
        m--;
    }
    int len=j-i+1;
    for(int iu=i;iu<=j;iu++)
    {
        ans[iu]=tmp;
        tmp++;
    }
    for(int iu=1;iu<=n;iu++)
    {
        printf("%d ",ans[iu]);
    }
    printf("\n");
}

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

D - Test of Love

依题意模拟即可 就是遇到鳄鱼就直接打gg

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
int n,m,k;
void solve()
{
    scanf("%d%d%d",&n,&m,&k);
    string s;
    cin>>s;
    s='L'+s+'L';
    int p=0;
    while(p<=n)
    {
        if(s[p]=='L')
        {
            if((p+m>=n+1))
            {
                printf("YES\n");
                return ;
            }
            int t=p;
            for(int i=t+1;i<=t+m;i++)
            {
                if(s[i]=='L')
                {
                    p=i;
                    break;
                }
            }
            if(t==p)
            {
                p=p+m;
            }
        }
        else if(s[p]=='W')
        {
            int t=p;
            for( int i = t + 1; i <= t + k; i++ )
            {
                if(s[i]=='L')
                {
                    p=i;
                    k-=i-t;
                    break;
                }
                if(s[i] == 'C')
                {
                    printf("NO\n");
                    return ;
                }
            }
            if(p==t)
            {
                printf("NO\n");
                return ;
            }
        }
        else
        {
            printf("NO\n");
            return ;
        }
    }
    printf("YES\n");
    return ;
}

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

E - Novice's Mistake

因为范围也就100嘛 所以挂后台慢慢跑跑出来 然后打表 预处理代码如下

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
string change(int a,int b,string s)
{
    //将字符串s重复a次并删去最后b个字符
    string t;
    for(int i=1;i<=a;i++)
    {
        t+=s;
    }
    for(int i=1;i<=b;i++)
    {
        t.pop_back();
    }
    return t;
}

int main()
{
    for(int i=2;i<=100;i++)
    {
        printf("n=%d\n",i);
        int cnt=0;
        for(int a=1;a<=10000;a++)
        {
            for(int b=1;b<=min(10000,a*i);b++)
            {
                if(to_string(a*i-b)==change(a,b,to_string(i)))
                {
                    printf("a=%d b=%d\n",a,b);
                    cnt++;
                }
            }
        }
        printf("cnt=%d\n\n",cnt);
    }
    return 0;
}

值得一提的是这个代码从2开始计算 因为1满足条件的情况太多 所有{i+1,i}都满足条件 所以实际代码当中我们对1进行特判

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
vector<pii> ans[150];
void ini()
{
    ans[2].push_back({20,18});
    ans[2].push_back({219,216});
    ans[2].push_back({2218,2214});
    ans[3].push_back({165,162});
    ans[4].push_back({14,12});
    ans[4].push_back({147,144});
    ans[4].push_back({1480,1476});
    ans[5].push_back({138,135});
    ans[7].push_back({129,126});
    ans[10].push_back({1262,2519});
    ans[11].push_back({12,21});
    ans[11].push_back({123,242});
    ans[11].push_back({1234,2463});
    ans[13].push_back({119,234});
    ans[14].push_back({1178,2351});
    ans[16].push_back({1154,2303});
    ans[18].push_back({1136,2267});
    ans[20].push_back({112,220});
    ans[21].push_back({11,19});
    ans[24].push_back({110,216});
    ans[35].push_back({107,210});
    ans[68].push_back({104,204});
    ans[90].push_back({1033,2061});
    ans[94].push_back({1032,2059});
}

int main()
{
    int T=1;
    scanf("%d",&T);
    ini();
    while(T--)
    {
        int n;
        scanf("%d",&n);
        if(n==1)
        {
            printf("9999\n");
            for(int i=1;i<=9999;i++)
            {
                printf("%d %d\n",i+1,i);
            }
            continue;
        }
        printf("%d\n",ans[n].size());
        for(auto p:ans[n])
        {
            printf("%d %d\n",p.first,p.second);
        }
    }
    return 0;
}

2024_SCAU暑期个人排位赛4

F - Rebranding

哥们儿真服了 今天又被jiejiejiang抢了首杀 那个题目都弹出来我是首杀了 结果他提交的比较早 真的就差这么一点点啊 气死了 天天被jiejiejiang抢首杀

 说回这道题 其实就是开个映射 每次更新都是26 最后根据这个映射输出即可

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <cstdio>
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);
    char to[200];
    for(int i='a';i<='z';i++)
    {
        to[i]=i;
    }
    string s;
    cin>>s;
    while(m--)
    {
        char a,b;
        cin>>a>>b;
        for(int j='a';j<='z';j++)
        {
            if(to[j]==a)
            {
                to[j]=b;
            }
            else if(to[j]==b)
            {
                to[j]=a;
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        printf("%c",to[s[i]]);
    }
}

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

B - Enter to the best problem of this contest!

怎么现在都流行拿交互题当签到啊

这道题要求只能询问29次 所以很容易想到二分 我们先问根节点 然后dfs下去 每次问他的左儿子 如果左儿子距离要查找点的距离比他自己的距离小1 说明是左儿子的子孙 再递归左儿子 如果比他大1 说明是右儿子的子孙 递归右儿子 最后如果距离是0就直接输出即可

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void dfs(int x,int dis)
{
    if(dis==0)
    {
        printf("! %d\n",x);
        fflush(stdout);
        return ;
    }
    printf("%d\n",2*x);
    fflush(stdout);
    int bk;
    scanf("%d",&bk);
    if(bk==dis+1)
        dfs(2*x+1,dis-1);
    else
        dfs(2*x,bk);
}

void solve()
{
    int n;
    scanf("%d",&n);
    printf("1\n");
    fflush(stdout);
    int bk;
    scanf("%d",&bk);
    dfs(1,bk);
}

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

C - Valera and Contest

这题我因为分母没判0 直接re11 关键是我还交了4发 中间还整个重写两次 最后才发现

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int a[1080];

void solve()
{
    int n,k,l,r,sall,sk;
    scanf("%d%d%d%d%d%d",&n,&k,&l,&r,&sall,&sk);
    int avg=sk/k;
    int tmp=sk%k;
    for(int i=1; i<=k; i++)
    {
        a[i]=avg;
    }
    int i;
    for(i=1; tmp>0 and i<=k; i++)
    {
        a[i]++;
        tmp--;
    }
    r=a[k];
    int q=n-k,sq=sall-sk;
    if(q!=0)
    {
        avg=sq/q;
        tmp=sq%q;
        for(int i=k+1; i<=n; i++)
        {
            a[i]=avg;
        }
        for(i=k+1; tmp>0 and i<=n; i++)
        {
            a[i]++;
            tmp--;
        }
    }
    for(int iu=1; iu<=n; iu++)
        printf("%d ",a[iu]);
    printf("\n");
}

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

E - Ticket Game

又是博弈论 这次我们这个捣乱的先手Monocarp每次都让本来就较多的那一半疯狂加9 那么守序正义Bicarp就疯狂在另外一边加9救场 直到只剩一边 Monocarp可能会全加0让Bicarp全加9都够不上另外一边 也可能全加0让这里远超对面 所以必须相等才行 我一开始就没判断最后这个WA23了两发

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <cstdio>
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);
    string s;
    cin>>s;
    int left=0,right=0;
    int sl=0,sr=0;
    for(int i=0;i<n/2;i++)
    {
        if(s[i]=='?')
            left++;
        else
            sl+=s[i]-'0';
    }
    for(int i=n/2;i<n;i++)
    {
        if(s[i]=='?')
            right++;
        else
            sr+=s[i]-'0';
    }
    int tmp=min(left,right);
    left-=tmp;
    right-=tmp;
    int del=abs(sl-sr);
    if(sl==sr)
    {
        if(left==right)
            printf("Bicarp\n");
        else
            printf("Monocarp\n");
        return ;
    }
    int bi=(left+right)/2*9;
    if(left==0)
    {
        if(sr+bi!=sl)
            printf("Monocarp\n");
        else
            printf("Bicarp\n");
    }
    else
    {
        if(sl+bi!=sr)
            printf("Monocarp\n");
        else
            printf("Bicarp\n");
    }
}

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

D - Road to Cinema

扫雷+消消乐半小时后惊闻CatBiscuit写出来了 遂写 先想的是距离排序然后后缀和 用二分搜索

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=200010;
struct car
{
    ll c;
    ll v;
    ll t;
}all[N];
ll del[N];
ll sum[N];
ll n,k,s,t;
bool cmp(car a,car b)
{
    return a.c<b.c;
}

void solve()
{
    scanf("%lld%lld%lld%lld",&n,&k,&s,&t);
    for(int i=0;i<n;i++)
    {
        scanf("%lld%lld",&all[i].c,&all[i].v);
        all[i].t=s/2;
    }
    ll lst=0;
    for(int i=0;i<k;i++)
    {
        ll now;
        scanf("%lld",&now);
        del[i]=now-lst;
        lst=now;
    }
    del[k]=s-lst;
    sort(del,del+k+1);
    sum[k+1]=0;
    for(int i=k;i>=0;i--)
    {
        sum[i]=sum[i+1]+del[i];
    }
    sort(all,all+n,cmp);
    for(int i=0;i<n;i++)
    {
        int p=upper_bound(del,del+k+1,all[i].v)-del;
        all[i].t+=sum[p]*2-(k-p)*all[i].v;
        //printf("all[%d].t=%d,c=%d,v=%d   p=%d   sum=%d\n",i,all[i].t,all[i].c,all[i].v,p,sum[p]);
    }
    printf("-1\n");
}

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

大概长这样 当然到最后都没有完全写完 因为发现那个公式里面奇偶的处理特别麻烦 判断条件特别多

后来发现完全可以直接二分答案 油箱的容量具有单调性 所以直接二分容量 再把车按价格排序 满足条件就输出就行

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=200010;
struct car
{
    ll c;
    ll v;
}all[N];
ll del[N];
ll n,k,s,t;
ll po[N];
bool cmp(car a,car b)
{
    return a.c<b.c;
}
bool check(int V)
{
    ll cnt=0;
    for(int i=0;i<=k;i++)
    {
        if(V<del[i]) return 0;
        if(V>2*del[i])
            cnt+=del[i];
        else
            cnt+=2*del[i]-V+del[i];
    }
    if(cnt<=t)
        return true;
    else
        return false;
}

void solve()
{
    scanf("%lld%lld%lld%lld",&n,&k,&s,&t);
    for(int i=0;i<n;i++)
    {
        scanf("%lld%lld",&all[i].c,&all[i].v);
    }
    for(int i=0;i<k;i++)
    {
        scanf("%d",&po[i]);
    }
    sort(po,po+k);
    int lst=0;
    for(int i=0;i<k;i++)
    {
        del[i]=po[i]-lst;
        lst=po[i];
    }
    del[k]=s-lst;
    sort(del,del+k+1);
    sort(all,all+n,cmp);
    int l=0,r=1e9;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(check(mid))
            r=mid-1;
        else
            l=mid+1;
    }
    //printf("%d\n",l);
    for(int i=0;i<n;i++)
    {
        if(all[i].v>=l)
        {
            printf("%d\n",all[i].c);
            return ;
        }
    }
    printf("-1\n");
}

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

G - New Reform

阅读理解系列 样例看不懂 看懂之后确实能反应过来是求环 因为环内的点我一定可以保证互不为孤岛 其他的就总得有那么一个点成为孤岛 直接使用并查集即可

#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=100010;
int pre[N],n,m;
bool st[N];//标记是不是在环内
int find(int x)
{
    if(pre[x]!=x) pre[x]=find(pre[x]);
    return pre[x];
}

void solve()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) pre[i]=i;
    while(m--)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        int fx=find(x),fy=find(y);
        if(fx!=fy)
        {
            pre[fx]=fy;
            if(st[fx] or st[fy] or st[x] or st[y])
                st[fx]=st[fy]=st[x]=st[y]=true;
        }
        else
        {
            st[fx]=st[fy]=st[x]=st[y]=true;
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(pre[i]==i and !st[i]) ans++;
    }
    printf("%d\n",ans);
}

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

J - Sorting the Coins

也是题意没咋看懂 看懂就还好 就是开局只有固定的硬币是反面朝上的 然后问你操作多少次对整个数组每次只要有一个反面正面相邻就交换位置使得无法继续操作 简单打几个就能找到规律了 最终不能移动也就意味着反面朝上的硬币统一出现在最后面 每个硬币移过去的操作次数是固定的 也就是距离最右边的长度 除非最右边已经是连续的反面朝上的硬币了 那就更新最右端就行

#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=300010;
int a[N],ned,ed;

int main()
{
    int n;
    scanf("%d",&n);
    printf("1 ");
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        if(i==n)
        {
            printf("1\n");
            return 0;
        }
        a[x]=1;
        for(int j=n-ned;a[j];j--)
        {
            ned++;
            ed++;
        }
        printf("%d ",i-ed+1);
    }
    return 0;
}

I - Longest Subsequence

有点像埃氏筛 就是对于每一个数 他的可以无条件加入所有lcm算出来是他的倍数的子串使得这个子串的长度加1 值得一提的事大于1e6的数字可以直接放弃 然后正常开桶即可

#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=1000010;
int a[N],st[N],cnt[N];
bool flag[N];
int n,m;
int now=1,ans=0;

void solve()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]<=m)
            cnt[a[i]]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(a[i]>m or flag[a[i]])
            continue;
        for(int j=1;a[i]*j<=m;j++)
            st[a[i]*j]+=cnt[a[i]];
        flag[a[i]]=true;
    }
    for(int i=1;i<=m;i++)
    {
        if(st[i]>ans)
        {
            ans=st[i];
            now=i;
        }
    }
    printf("%d %d\n",now,ans);
    for(int i=1;i<=n;i++)
    {
        if(now%a[i]==0)
            printf("%d ",i);
    }
    printf("\n");
}

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

牛客周赛 Round 51

A - 小红的同余

依题意模拟即可

#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 m;
    cin>>m;
    cout<<(m+1)/2<<endl;
    return 0;
}

B - 小红的三倍数

这次真的是我们小学二年级就学过的三的倍数的各位数相加等于3

#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;
    cin>>n;
    int sum=0;
    for(int i=0;i<n;i++)
    {
        string s;
        cin>>s;
        for(int j=0;j<s.size();j++)
            sum+=s[j]-'0';
    }
    if(sum%3==0)
        cout<<"YES"<<endl;
    else
        cout<<"NO"<<endl;
    return 0;
}

C - 小红充电

依题意模拟即可

#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()
{
    db x,y,t,a,b,c;
    cin>>x>>y>>t>>a>>b>>c;
    db ans=1e18;
    if(x<=t)
    {
        ans=min(ans,(100-x)/c);
        ans=min(ans,(100-x)/a);
        ans=min(ans,(100-x)/b);
        printf("%.10lf\n",ans);
    }
    else
    {
        ans=min(ans,(100-x)/a);
        ans=min(ans,(100-x)/b);
        ans=min(ans,(x-t)/y+(100-t)/c);
        printf("%.10lf\n",ans);
    }
    return 0;
}

D - 小红的gcd

C++直接用algorithm里面的gcd是85.71

#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()
{
    ll a,b;
    cin>>a>>b;
    cout<<__gcd(a,b)<<endl;
    return 0;
}

Python用math库的gcd是152.38 因为这个数据连Python都爆了

import math
a=int(input())
b=int(input())
print(math.gcd(a,b))

我们C++还可以预处理一下 把前面的每一位单独考虑 这样是142.86

#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;
string a;
int b;
int main()
{
    cin>>a>>b;
    //求gcd(a,b) 其中a长度大于1e6
    int ans=0;
    for(int i=0;i<a.size();i++)
    {
        ans=(ans*10+a[i]-'0')%b;
    }
    cout<<__gcd(ans,b)<<endl;
    return 0;
}

我当时居然没有拿Python把这个思路再写一遍 写一遍就过了啊啊啊啊啊

a = input()
b = int(input())
r = 0
for x in a:
    r = r * 10 + int(x)
    r %= b
import math

print(math.gcd(r , b))

E - 小红走矩阵

不难看出答案具有单调性 如果可以让较小的权值成立 那么比他大的一定也成立

#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;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
const int N=555;
int n;
int mp[N][N];
bool st[N][N];
bool check(int now)
{
    memset(st,false,sizeof st);
    queue<pii> q;
    q.emplace(1,1);
    while(!q.empty())
    {
        pii t=q.front();
        q.pop();
        if(t.first==n and t.second==n)
            return true;
        for(int i=0;i<4;i++)
        {
            int x=t.first+dx[i];
            int y=t.second+dy[i];
            if(x<1 or x>n or y<1 or y>n or st[x][y] or mp[x][y]>now)
                continue;
            st[x][y]=true;
            q.emplace(x,y);
        }
    }
    return false;
}

void solve()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%lld",&mp[i][j]);
    int l=1,r=1e9+10;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(mid))
            r=mid;
        else
            l=mid+1;
    }
    printf("%lld\n",l);
}

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

 2024_SCAU暑期个人排位赛5

B - Telephone Number

依题意模拟即可

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    int n;
    cin>>n;
    string s;
    cin>>s;
    int i;
    for(i=0;i<n;i++)
    {
        if(s[i]=='8')
            break;
    }
    if(i==n)
    {
        printf("NO\n");
        return ;
    }
    if(n-i>=11)
    {
        printf("YES\n");
        return ;
    }
    printf("NO\n");
    return ;
}

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

F - Frodo and pillows

先给没人分配一个枕头 然后我们注意到每想要给Frodo加一个枕头 旁边所有人要同步加一个 所以就往两边维护每给他加一个枕头一共要加多少个枕头即可

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int n,m,k;

void solve()
{
    scanf("%d%d%d",&n,&m,&k);
    ll ans=1;
    m-=n;
    ll row=1;
    int l=k,r=k;
    while(row<=m and row<n)
    {
        m-=row;
        ans++;
        if(l>1) row++;
        if(r<n) row++;
        l--;
        r++;
    }
    ans+=m/n;
    printf("%lld\n",ans);
}

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

E - Weird Sum

一开始想的是把之前每一个数字的所有点的坐标加起来 再维护有多少个 每次直接用这一次的坐标*次数-维护的坐标和 但是样例都过不了 发现是绝对值的问题 有的值本来会产生负面影响但是加在一起就不一定了 

考虑遍历两次 分别保证后面的x坐标一定比前面的大和y坐标一定比前面的大 这样的话我们分开来就可以过了

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=100010;
ll cnt[N];
ll sum[N];

void solve()
{
    int n,m;
    scanf("%d%d",&n,&m);
    ll mp[n+1][m+1];
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%lld",&mp[i][j]);
        }
    }
    memset(cnt,0,sizeof(cnt));
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            ll t=mp[i][j];
            ans+=cnt[t]*i-sum[t];
            cnt[t]++;
            sum[t]+=i;
        }
    }
    memset(cnt,0,sizeof(cnt));
    memset(sum,0,sizeof(sum));
    for(int j=1;j<=m;j++)
    {
        for(int i=1;i<=n;i++)
        {
            ll t=mp[i][j];
            ans+=cnt[t]*j-sum[t];
            cnt[t]++;
            sum[t]+=j;
        }
    }
    printf("%lld\n",ans);
}

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

K - Minimum Ties

构造 我的构造方式是1和-1交替 然后是偶数的话就在没有0的每一行第一个放一个0 记得另外一边要同步维护和更新

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#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;
int mp[150][150];
bool zeroed[150];
int now[150];

void solve()
{
    int n;
    scanf("%d",&n);
    memset(mp,0,sizeof(mp));
    memset(now,0,sizeof(now));
    memset(zeroed,true,sizeof(zeroed));
    if(n%2==0)
        memset(zeroed,false,sizeof(zeroed));
    for(int i=1; i<n; i++)
    {
        for(int j=i+1; j<=n; j++)
        {
            if(zeroed[i]==false)
            {
                zeroed[i]=true;
                zeroed[j]=true;
                mp[i][j]=0;
                mp[j][i]=0;
                continue;
            }
            if(now[i]<0)
            {
                mp[i][j]=1;
                now[i]++;
                mp[j][i]=-1;
                now[j]--;
            }
            else if(now[i]>0)
            {
                mp[i][j]=-1;
                now[i]--;
                mp[j][i]=1;
                now[j]++;
            }
            else
            {
                if(now[j]<=0)
                {
                    mp[j][i]=1;
                    now[j]++;
                    mp[i][j]=-1;
                    now[i]--;
                }
                else if(now[j]>0)
                {
                    mp[j][i]=-1;
                    now[j]--;
                    mp[i][j]=1;
                    now[i]++;
                }
            }
        }
    }
    for(int i=1; i<n; i++)
    {
        for(int j=i+1; j<=n; j++)
            printf("%d ",mp[i][j]);
    }
}

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

G - 筛法

首先是这题我刚才发现我居然补过 就是2024西安交大校赛的O题 但是赛时一点印象没有

赛时就更抽象了 看到这条评论打了下表秒了

打完表就会发现输出n平方就可以了 但是我忘了删多测wa了一发 要不然哥们儿今天就前十了

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#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;

void solve()
{
    ll n;
    scanf("%lld",&n);
    printf("%lld\n",n*n);
}

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

I - Watto and Mechanism 

Trie树 感谢队友

2024 ICPC ShaanXi Provincial Contest 

西安交大的比赛一如既往地高质量 虽然好像没够到铜牌😭😭😭

F - Try a try, AC is OK

求最大值即可

#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 m=0;
    for(int i=0;i<n;i++)
    {
        int x;
        scanf("%d",&x);
        m=max(m,x);
    }
    printf("%d\n",m);
}
 
int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

M - Window Decoration

开三维数组记录每个格子的四个小三角形的情况 数据范围只到100所以随便过

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

void solve()
{
    int n;
    scanf("%d",&n);
    int cnt=0;
    for(int i=0;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if(mp[x+1][y+1][2]==false)
        {
            mp[x+1][y+1][2]=true;
            cnt++;
        }
        if(mp[x+1][y+1][3]==false)
        {
            mp[x+1][y+1][3]=true;
            cnt++;
        }
        if(mp[x][y+1][3]==false)
        {
            mp[x][y+1][3]=true;
            cnt++;
        }
        if(mp[x][y+1][4]==false)
        {
            mp[x][y+1][4]=true;
            cnt++;
        }
        if(mp[x+1][y][1]==false)
        {
            mp[x+1][y][1]=true;
            cnt++;
        }
        if(mp[x+1][y][2]==false)
        {
            mp[x+1][y][2]=true;
            cnt++;
        }
        if(mp[x][y][1]==false)
        {
            mp[x][y][1]=true;
            cnt++;
        }
        if(mp[x][y][4]==false)
        {
            mp[x][y][4]=true;
            cnt++;
        }
    }
    double ans=0.25*cnt;
    printf("%.10lf\n",ans);
}

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

A - chmod

依题意模拟即可

#include<bits/stdc++.h>
#include<cstring>
using namespace std;
const long long N=1e7+20;
long long a[600][600],b[600][600],n;
const long long dx[]={0,0,1,-1};
const long long dy[]={-1,1,0,0};


void solve()
{
  long long i,j,m,k,l,r,mid;
  string s;
  cin>>s;
  for(i=0;i<3;i++)
  {
      k=s[i]-'0';
      if(k==0)
        cout<<"---";
      if(k==1)
        cout<<"--x";
      if(k==2)
        cout<<"-w-";
      if(k==3)
        cout<<"-wx";
      if(k==4)
        cout<<"r--";
      if(k==5)
        cout<<"r-x";
      if(k==6)
        cout<<"rw-";
      if(k==7)
        cout<<"rwx";
  }
  cout<<endl;

}
int main()
{
	long long t;
    t=1;
    cin>>t;
    while(t--)
        solve();
	return 0;
}

G - Disappearing Number

先想到的是消失的数为9的情况 那就是直接进制转换 九进制转十进制就行 后来发现不仅如此 如果消失的是其他的数字一样也只需要把大于他的数字全部减一然后进制转换即可

#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;
    int n;
    cin>>s>>n;
    int m=s.size();
    int a[m];
    for(int i=0;i<m;i++)
    {
        a[i]=s[i]-'0';
        if(a[i]>n)
            a[i]--;
    }
    //九进制转十进制
    ll ans=0;
    for(int i=0;i<m;i++)
    {
        ans=ans*9+a[i];
    }
    ans++;
    printf("%lld\n",ans);
}

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

上半月完结啦!下半月主要就是牛客多校了 我们明天见! 

在实际工作中应用高效工作复盘-O混合式课程所学可以帮助你提升工作效率和质量,以及提供更好的自我和团队协作能力。以下是可能的改变和解决问题的方法: 1. 识别复盘中存在的问题:OMO混合式课程可能帮助你认识到你在复盘过程中可能存在的问题,比如缺乏系统性、不够深入、忽视重要细节等。你可以通过学习课程中的方法和技巧,更好地识别问题并加以解决。 2. 提高复盘效率:OMO混合式课程可能教授了一些高效的复盘方法,例如SMART目标设定、5W1H问题分析法、鱼骨图等。通过学习这些方法,你可以更迅速地找到问题根源、制定解决方案,并在实际工作中提高复盘效率。 3. 提升自我管理能力:OMO混合式课程可能强调了自我管理的重要性,例如时间管理、优先级排序、任务分解等。这些技能可以帮助你更好地组织和规划工作,提高自我效能感,并更好地应对工作挑战。 4. 加强团队协作能力:OMO混合式课程可能涉及到团队复盘和共享经验的内容。通过学习这些课程,你可以了解如何在团队中进行有效的复盘和知识分享,促进团队学习和协作,提高整个团队的绩效。 综上所述,通过应用高效工作复盘-OMO混合式课程所学,你可能会改善复盘中存在的问题,并在实际工作中提高工作效率、自我管理能力和团队协作能力。这将有助于你更好地应对工作挑战,取得更好的成果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值