9.【2024初三集训模拟测试1】

\(\Huge打了一场模拟赛,又垫底了。qwq\)

2024初三集训模拟测试1

T1edit

\(30pts\)

前言

  • 被签到题薄纱了。
  • 由于没看清题面以为是个数字就要输出空格然后 \(\Large④\)\(qwq\Huge😓😓😓😅\)
  • 是个人就能薄纱蒟蒻 \(qwq\)

(后言)\(\Huge🈚\)

代码

#include<bits/stdc++.h>
#define sort stable_sort
using namespace std;
namespace IO
{
    #define ll long long
    const int MAX=1<<24;
    char buf[MAX],*p1=buf,*p2=buf;
    char obuf[MAX],*o=obuf;
    #define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
    //template<typename T>
    //inline T read()
    inline int read()
    {
        int x=0;bool f=1;
        char c=gc();
        for(;c<48||c>57;c=gc())if(c=='-')f=0;
        for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
        return f?x:~x+1;
    }
    void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
    void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
    void write(ll x,char end){pit(x);*o++=end;}
    void flush(){fwrite(obuf,o-obuf,1,stdout);}
    #undef ll
}
using IO::read;using IO::write;using IO::flush;using std::complex;
inline int min(int x,int y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline int max(int x,int y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
long long n,m;
void init_set()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    #ifdef ONLINE_JUDGE
    freopen("edit.in","r",stdin);
    freopen("edit.out","w",stdout);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
}
char c[1010];
signed main()
{
    init_set();
    cin.getline(c,1000,'\n');
    for(int i(0);i<strlen(c);++i)
    {
        if(((c[i]>='A'&&c[i]<='Z')||(c[i]>='a'&&c[i]<='z'))&&(c[i+1]>=48&&c[i+1]<=57))cout<<c[i]<<' ';
        else if((c[i]>=48&&c[i]<=57)&&((c[i+1]>='A'&&c[i+1]<='Z')||(c[i+1]>='a'&&c[i+1]<='z')))cout<<c[i]<<' ';
        else cout<<c[i];
    }
    flush();
    return 0;
}

T2game

\(60pts\)

题解

  • 又是 \(Bob\) ,但是 \(Alice\) 不是 \(Ayano\)
  • \(Alice\) 想要最大化得分, \(Bob\) 想要最小化得分,只有 \(Alice\) 可以一次擦掉多个整数,得分是 \(Alice\) 擦掉整数的总和,并且 \(Alice\) 先手,所以 \(Alice\) 开局一定会把所有正数拿走。
  • 之后就要考虑负数,如果最小的负数极小,那么 \(Alice\) 一定会避免擦掉最小的负数。如果正好是 \(Bob\) 擦掉这个负数,那么不需要额外行动,否则就要在一开始擦掉最大的负数,从而避免擦掉最小的负数。
  • 因此要考虑 \(Alice\) 开局时要擦掉 \(1\) 个负数还是不擦。
  • 对于 \(Alice\) ,只有第一轮会擦掉多个数。因为负数擦的越多得分越少,如果留给 \(Bob\) 还能避免损失。
  • 还有一点要注意,加入数据全是负数,那么就需要特判一下,要让 \(Alice\) 先手拿走负数,那么就要选 \(1\)\(2\) 个负数了。

代码

#include<bits/stdc++.h>
#define int long long
#define N (1)
#define sort stable_sort
using namespace std;
namespace IO
{
    #define ll long long
    const int MAX=1<<24;
    char buf[MAX],*p1=buf,*p2=buf;
    char obuf[MAX],*o=obuf;
    #define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
    //template<typename T>
    //inline T read()
    inline int read()
    {
        int x=0;bool f=1;
        char c=gc();
        for(;c<48||c>57;c=gc())if(c=='-')f=0;
        for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
        return f?x:~x+1;
    }
    void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
    void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
    void write(ll x,char end){pit(x);*o++=end;}
    void flush(){fwrite(obuf,o-obuf,1,stdout);}
    #undef ll
}
using IO::read;using IO::write;using IO::flush;using std::complex;
inline int min(int x,int y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline int max(int x,int y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
long long n,m;
void init_set()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    #ifdef ONLINE_JUDGE
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
}
bool pd[100010];
int l,r,xx,yy,zz,lss,T;
int a[100010];
int score,cnt,ls1,ls2,ls3;
signed main()
{
    init_set();
    n=read();
    for(int i(1);i<=n;++i)
    {
        a[i]=read();
        if(a[i]>=0)score+=a[i],++cnt;
    }
    if(n==1)cout<<a[1],exit(0);
    sort(a+1,a+1+n);
    if(!cnt)
    {
        for(int i(n),j(1);i;--i,++j)
        {
            if(j&1)ls1+=a[i];
            else continue;
        }
        if(n-1>=1)
        {
            ls2+=a[n];
            for(int i(n-1),j(1);i;--i,++j)
            {
                if(j&1)ls2+=a[i];
                else continue;
            }
        }
        else ls2=-1e13;
        write(score+max({ls1,ls2}),'\n');
        flush();exit(0);
    }
    n-=cnt;
    for(int i(n),j(2);i;--i,++j)
    {
        if(j&1)ls1+=a[i];
        else continue;
    }
    if(n-1>=1)
    {
        ls2+=a[n];
        for(int i(n-1),j(2);i;--i,++j)
        {
            if(j&1)ls2+=a[i];
            else continue;
        }
    }
    else ls2=-1e13;
    write(score+max({ls1,ls2}),'\n');
    flush();
    return 0;
}

T3score

\(70pts\)

  • 赛时想的部分分算法(不就是暴力¿؟?¿)。

题解

  • 给定一组数据, \(1\leq A_i\leq 100\) 。之后求出每个连续区间 \(\large[l,r]\) 的平均数是否为整数,求有多少区间满足平均数为整数。
  • 暴力就是暴力, \(\large n^2\) 就是 \(\large n^2\)\(\large n^2\) 过不了 \(\large 10^5\) 。。。
  • 正解是枚举平均数 \(t\) ,之后将被减去 \(t\) 的前缀和 \(\large s_i\) 存到堆里,然后通过任意两个相同的前缀和可以得出平均数为 \(t\) 的区间,之后计数即可。

代码

  • 空间复杂度可能略大 \(qwq\)
#include<bits/stdc++.h>
#define N (10000010)
#define sort stable_sort
using namespace std;
namespace IO
{
    #define ll long long
    const int MAX=1<<24;
    char buf[MAX],*p1=buf,*p2=buf;
    char obuf[MAX],*o=obuf;
    #define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
    //template<typename T>
    //inline T read()
    inline int read()
    {
        int x=0;bool f=1;
        char c=gc();
        for(;c<48||c>57;c=gc())if(c=='-')f=0;
        for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
        return f?x:~x+1;
    }
    void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
    void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
    void write(ll x,char end){pit(x);*o++=end;}
    void flush(){fwrite(obuf,o-obuf,1,stdout);}
    #undef ll
}
using IO::read;using IO::write;using IO::flush;using std::complex;
inline int min(int x,int y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline int max(int x,int y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline void swap(int &x,int &y){x^=y^=x^=y;}
long long n,m;
void init_set()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    #ifdef ONLINE_JUDGE
    freopen("score.in","r",stdin);
    freopen("score.out","w",stdout);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
}
bool kampf=true;
int l,r,xx,yy,zz,lss,T;
int a[100010],sum[100010];
int de[110][100010];
bitset<(N<<1)>UN;
int adolf[N<<1];
vector<int>lis,US;
int ans,cnt;
signed main()
{
    init_set();
    n=read();
    for(signed i(1);i<=n;++i)
    {
        a[i]=read(),sum[i]=sum[i-1]+a[i];
        if(a[i]>2)kampf=false;
    }
    if(kampf)
    {
        ans=0;
        for(int i(1);i<=n;)
        {
            for(;a[i]==1;++i)ans+=++cnt;
            cnt=0;
            for(;a[i]==2;++i)ans+=++cnt;
            cnt=0;
        }
        write(ans,'\n');
        flush();
        exit(0);
    }
    for(int i(1);i<=100;++i)
    {
        for(int j(1);j<=n;++j)de[i][j]=de[i][j-1]+a[j]-i;
        for(int j(0);j<=n;++j)
        {
            ++adolf[de[i][j]+N],
            lis.push_back(de[i][j]+N);
        }
        for(int j:lis)
        {
            if(!UN[j])
            {
                US.push_back(j);
                UN[j]=true;
                ans+=((adolf[j]*(adolf[j]-1))>>1);
            }
            --adolf[j];
        }
        for(int j:US)UN[j]=false;
        lis.clear();US.clear();
    }
    write(ans,'\n');
    flush();
    return 0;
}

T4city

\(60pts\)

  • 更抽象的一集。。。 \(\Huge😅😅😅😅😅😅😅\) \(\Huge٭٭٭٭٭٭٭\) \(\Huge⁂⁂⁂⁂⁂⁂⁂\) 。为啥输出 \(-1\)\(60\) 分؟؟؟؟؟؟؟¿¿¿¿¿¿¿但是打正解也是 \(60\) 分,因为当时没有 \(special\) \(judge\) ,而是文本比较。

题解

  • 首先求出来最少连边和最多连边,以及是否还有连到 \(x\) 个城市群的机会,之后就能求出 \(-1\) 的情况, \(-1\) 当然 \(\Huge梅西\) ,否则 \(\Huge呦西\)
    image
  • 当然, \(\Huge梅西\) 的情况可以得 \(60\) 的高分,而 \(\Huge呦西\) 的情况只有 \(40\) 分。
  • 最少连边是 \(\Large\sum\limits_{i=1}^x|S_i|[|S_i|>1]\) 条边,最多连边是 \(\Large\sum\limits_{i=1}^x|S_i|\times|S_i-1|+\sum\limits_{i=1}^x\sum\limits_{j=i+1}^x|S_i||S_j|\) ,而且还可以通过“修改内部数据”使得边更多。因此肉眼可见边非常多,因此这个 \(-1\) 骗不到分,除非数据故意卡最多边。
  • 而在这其中,连到满足情况后就可以开始放肆地瞎连了。
  • 实际上写代码时,发现 \(x=1\) 的情况怎么也过不去,思考过后,发现可以进行特判。由于所有点都在一个连通块里,于是可以连一个环,之后在其中随便连边,边的数量足够即可。(但是也可能是因 \(x\) 比要求在同一个连通块里的个数多,但是却没有进行合并,之后就错了)。

代码

  • 但是很可能有很多问题 \(qwq\Huge😓😓😓\)
#include<bits/stdc++.h>
#define int long long
#define N (1)
#define sort stable_sort
using namespace std;
namespace IO
{
    #define ll long long
    const int MAX=1<<24;
    char buf[MAX],*p1=buf,*p2=buf;
    char obuf[MAX],*o=obuf;
    #define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
    //template<typename T>
    //inline T read()
    inline int read()
    {
        int x=0;bool f=1;
        char c=gc();
        for(;c<48||c>57;c=gc())if(c=='-')f=0;
        for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
        return f?x:~x+1;
    }
    void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
    void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
    void write(ll x,char end){pit(x);*o++=end;}
    void flush(){fwrite(obuf,o-obuf,1,stdout);}
    #undef ll
}
using IO::read;using IO::write;using IO::flush;
inline int min(int x,int y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline int max(int x,int y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline void swap(int &x,int &y){x^=y^=x^=y;}
long long n,m;
void init_set()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    #ifdef ONLINE_JUDGE
    freopen("city.in","r",stdin);
    freopen("city.out","w",stdout);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
}
bool kampf=true;
int pd[1000010];
vector<int>e[1000010],re;
int a[1000010];
int ans,cnt,cnm,p,q;
int f[1000010],mi,mx,ed;
int x[1000010],y[1000010];
int find(int x)
{
    if(f[x]!=x)return f[x]=find(f[x]);
    return f[x];
}
void unionf(int x,int y)
{
    x=find(x),y=find(y);
    if(x<y)f[x]=y;
    else f[y]=x;
}
signed main()
{
    init_set();
    n=read(),m=read(),p=read(),q=read();
    for(int i(1);i<=n;++i)f[i]=i;
    for(int i(1);i<=q;++i)
        x[i]=read(),y[i]=read(),unionf(x[i],y[i]);
    for(int i(1);i<=n;++i)
    {
        if(!pd[find(i)]);
        ++pd[find(i)],e[find(i)].push_back(i);
    }
    for(int i(1);i<=n;++i)
    {
        if(pd[find(i)]==1)re.push_back(i);
        if(pd[find(i)]>1)++cnt;
        if(pd[i]>1)++cnm;
    }
    if(n-cnt+cnm<p)puts("-1"),exit(0);//能建出来的城市群少于要求的城市群
    if(m+p<=n)puts("-1"),exit(0);//能建出来的城市群多于要求的城市群
    if(p==1)
    {
        for(int i(1);i<n;++i)write(i,' '),write(i+1,'\n'),++ed;
        write(n,' '),write(1,'\n'),++ed;
        for(int i(2);i<n&&ed<m;++i)
        {
            for(int j(1);j<=n-i&&ed<m;++j)
            {
                write(j,' '),write(i+j,'\n'),++ed;
            }
        }
        flush();
        exit(0);
    }
    for(int i(1);i<=n;++i)
        mi+=((pd[i]>1)?pd[i]:0);//,mx+=((pd[i]>1)?(pd[i]*(pd[i]-1)):0);
    for(int i(0);i<re.size()-1&&ed<=n-cnt+cnm-p;++i)
    {
        if(ed==n-cnt+cnm-p)
        {
            write(re[i],' '),write(re[0],'\n'),++ed;
            for(int j(1);j<=i;++j)unionf(re[0],re[j]),e[re[0]].push_back(re[j]);
            pd[re[0]]+=i;
            break;
        }
        else
            write(re[i],' '),write(re[i+1],'\n'),++ed;
    }
    for(int i(1);i<=n&&ed<m;++i)
    {
        if(pd[i]>1&&i!=re[0])
        {
            for(int j(0);j<e[i].size()-1&&ed<m;++j)write(e[i][j],' '),write(e[i][j+1],'\n'),++ed;
            if(ed==m)break;
            write(e[i].back(),' '),write(e[i].front(),'\n'),++ed;
        }
    }
    //之后再连一些其他的边。
    for(int i(1);i<=n&&ed<m;++i)
    {
        if(pd[i]>2)
        {
            for(int j(0);ed<m&&j<e[i].size()-1;++j)write(e[i][j+1],' '),write(e[i][j],'\n'),++ed;
            if(ed==m)break;
            write(e[i].front(),' '),write(e[i].back(),'\n'),++ed;
        }
        if(pd[i]>2)
        {
            for(int j(2);j<e[i].size()-1&&ed<m;++j)
            {
                for(int k(0);k<e[i].size()-j&&ed<m;++k)
                {
                    write(e[i][k+j],' '),write(e[i][k],'\n'),++ed;
                }
            }
            if(ed==m)break;
            for(int j(2);j<e[i].size()-1&&ed<m;++j)
            {
                for(int k(0);k<e[i].size()-j&&ed<m;++k)
                {
                    write(e[i][k],' '),write(e[i][k+j],'\n'),++ed;
                }
            }
            if(ed==m)break;
        }
    }
    for(int i(1);i<=n&&ed<m;++i)
    {
        if(pd[i])
        {
            for(int j(i+1);j<=n&&ed<m;++j)
            {
                if(pd[j])
                {
                    for(int k1(0);k1<e[i].size()&&ed<m;++k1)
                    {
                        for(int k2(0);k2<e[j].size()&&ed<m;++k2)
                        {
                            write(e[i][k1],' '),write(e[j][k2],'\n'),++ed;
                        }
                    }
                }
            }
        }
    }
    flush();
    return 0;
}

\(\Huge但是打了一场模拟赛,又垫底了。qwq\)

posted @ 2024-02-19 17:31  minecraft114514  阅读(23)  评论(3编辑  收藏  举报