首页 > 其他分享 >初三奥赛模拟测试1

初三奥赛模拟测试1

时间:2024-03-10 10:11:43浏览次数:35  
标签:int 代码 long read 奥赛 初三 步数 模拟 getchar

前言

  • 比赛链接

  • 总分:\(107pts\)

    image

  • \(T1~79pts:\)

    坐标 \(DP\) ,赛时感觉打的是正解,但是打假了。

  • \(T2~28pts:\)

    理解错题了,以为是帮他调程序了,于是给人家调 \(TLE\) 了。

  • \(T3~0pts,T4~0pts:\)

    没啥好说的,不会。

  • 官方题解

T1 回文

点击查看题面

image

  • 部分分:

    部分分没什么好说的,大多集中在 \(79pts\) ,都是 \(DP\) 打假了的。

  • 正解:

    坐标 \(DP\) 。

    \(4\) 维的很好想,对于回文串的性质,从前往后跑和从后往前跑路径是一样的。

    那么定义 \(f[i][j][k][l]\) ,表示从前往后跑到 \(a[i][j]\) ,从后往前跑到 \(a[k][l]\) 时的方案数。

    但是 \(4\) 维肯定会 \(MLE\) ,之后发现第 \(4\) 维可以去掉,因为从前往后和从后往前跑路径始终是保持相同的,所跑的步数也一定是相同的,那么第 \(4\) 维 \(l\) 完全可以用 \(i,j,k\) 表示。

    • 解释一下:

      从 \(a[1][1]\) 跑到 \(a[n][m]\) ,需要走的步数为 \(n+m-1\) ,起点不算,那么均分下来,两边各需跑 \(maxx=\dfrac{n+m-1}{2}\) 步。

      那么对于从前往后的步数显然为 \(i+j-1\) ,起点不算,那么从后往前搜走的步数也一定是 \(i+j-1\) ;对于从后往前的步数同样的可以表示为 \((n-k+1)+(m-l+1)-1=i+j-1\) ,那么 \(l=m+n-i-j-k+2\) 。

    所以定义 \(f[i][j][k]\) 即可,第 \(4\) 维不是消失了,是可以用前 \(3\) 维表示,不需要存了。

    转移方程很好想,如果 \(a[i][j]=a[k][l]\) ,那么对于其下一步 \(f[i1][j1][k1]+=f[i][j][k]\) 即可。当然对于此时如果 \(i+j-1=maxx\) ,也就是已经匹配完了,就不需要转移了。

    不好搞的是统计答案。

    发现 \(m+n\) 奇偶不同时,统计答案也是不同的,若 \(n+m\) 为奇数时,他两边同时跑最后时到达一个点的;反之为偶数时,他最后会跑到相邻的两个点。

    如图:

    1. \(m+n\) 为奇数

      image

      讨论到达 \(ans\) 的前一刻 \(k,l\) 可能的位置,如图 \(1,2\) ,所以对于 \(k\) 的位置可能为 \(i,i+1\) ,\(l\) 的位置不用讨论,\(k\) 确定同时也就确定了。

    2. \(m+n\) 为偶数

      image

      讨论 \(k,l\) 在到达 \(ans2\) 上一步时可能的位置,如图 \(1,2,3\) ,同时注意 \(2\) 的贡献有两次,所以要家两次。所以 \(k\) 的位置可能为 \(i,i+1,i+2\) ,其中 \(i+1\) 的情况要算两遍。

    而至于 \(\%\) 的常数很大,可以打一个 \(mod\) 函数,看代码就知道了。

    点击查看代码
    #include<bits/stdc++.h>
    // #define int long long 
    #define endl '\n'
    using namespace std;
    const int N=510,P=993244853;
    template<typename Tp> inline void read(Tp&x)
    {
        x=0;register bool z=true;
        register char c=getchar();
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
        for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
        x=(z?x:~x+1);
    }
    int n,m,maxx;
    unsigned int f[N][N][N],ans;
    char a[N][N];
    int hx[5]={0,1,1,0,0},zx[5]={0,0,0,1,1},hy[5]={0,-1,0,-1,0},zy[5]={0,0,-1,0,-1};
    void mod(unsigned int &x) {x=(x>=P?x-P:x);}
    signed main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        read(n),read(m);
        maxx=(n+m-1)/2;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>a[i][j];
        if(a[1][1]!=a[n][m]) 
        {
            cout<<0;
            return 0;
        }
        f[1][1][n]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;i+j<=maxx+1&&j<=m;j++)
                for(int k=n;k>=i;k--)
                {
                    int l=m+n-i-j+2-k;
                    if(a[i][j]==a[k][l])
                    {
                        if(i+j!=maxx+1)
                            for(int x=1;x<=4;x++)
                            {
                                int i1=i+hx[x],j1=j+zx[x],k1=k+hy[x],l1=l+zy[x];
                                if(a[i1][j1]==a[k1][l1])
                                    f[i1][j1][k1]+=f[i][j][k],mod(f[i1][j1][k1]);
                            }
                    }
                }
        if(!((m+n)&1)) 
            for(int i=1;i<=min(n,maxx);i++)
            {
                for(int k=0;k<=2;k++)
                    {
                        int j=maxx-i+1;
                        ans+=f[i][j][i+k],mod(ans);
                    }
                ans+=f[i][maxx-i+1][i+1],mod(ans);
            }   
        else 
            for(int i=1;i<=min(n,maxx);i++)
                for(int k=0;k<=1;k++)
                {
                    int j=maxx-i+1;
                    ans+=f[i][j][i+k],mod(ans);
                }
        cout<<ans;
    }
    

    复杂度 \(O(n\times m\times n)\) 。

T2 快速排序

点击查看题面

image

  • 部分分:

    直接在给的快排函数上调,他那个代码时没有随机化的,会 \(TLE\) 的,所以我 \(TLE~28pts\) ,别人多少不知道了。

  • 正解:

    首先他那个快排是死的,我们自带的 \(stable\_sort\) 是有随机化的,直接用这个即可。

    然后分析他这个代码(分析样例)。

    对于当前位置如果是 \(nan\) 的话,就不动,直接输出。

    否则,就将所有比他小的数,包括他自己输出即可,当然输出过的就不再输出了。

    思路听起来很简单的,调代码就行了。

    实现就比较简单了,每个人方法可能不一样,直接看代码吧。

    点击查看代码
    #include<bits/stdc++.h>
    #define int long long 
    #define endl '\n'
    using namespace std;
    const int N=5e5+10;
    template<typename Tp> inline void read(Tp&x)
    {
        x=0;register bool z=true;
        register char c=getchar();
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
        for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
        x=(z?x:~x+1);
    }
    int t,n,b[N],tot,id[N];
    string a[N];
    bool v[N];
    signed main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        read(t);
        while(t--)
        {
            tot=0;
            memset(v,0,sizeof(v));
            memset(id,0,sizeof(id));
            memset(b,0,sizeof(b));
            read(n);
            for(int i=1;i<=n;i++)
            {
                cin>>a[i];
                if(a[i]=="nan") continue;
                int s=0;
                for(int j=0;j<a[i].size();j++)
                    s=s*10+a[i][j]-'0';
                b[++tot]=s,id[i]=b[tot];
            }
            stable_sort(b+1,b+1+tot);
            int j=0;
            for(int i=1;i<=n;i++)
            {
                if(a[i]=="nan")
                {
                    cout<<a[i]<<' ';
                    continue;
                }
                else 
                {
                    if(j==tot||b[j]>id[i]) continue;
                    while(++j)
                    {
                        if(b[j]) cout<<b[j]<<' ';
                        if(b[j]==id[i]||j==tot) break;
                    }
                }
            }
            cout<<endl;
        }
    }
    

    复杂度 \(O(n\log(n))\) ,带一定的常熟(将字符串转换为整型)。

标签:int,代码,long,read,奥赛,初三,步数,模拟,getchar
From: https://www.cnblogs.com/Charlieljk/p/18061577

相关文章

  • 关于 Linux 中模拟鼠标
    问题的背景是我想用自动化脚本来玩StardewValley的小游戏,刷钱,但是遇到了一系列问题,这里记录我的一些历程。pyautogui/pydirectinputpyautogui是我第一个考虑的方案。虽然可以正常的移动鼠标,点击,但是游戏内却没有点击事件。搜索发现一般游戏在windows下使用的是directX,所......
  • NOIP2024 模拟赛1
    \(2023\)赛年的结束,\(2024\)赛年的开始。我们会继续前行,也永远会。如今走过这世间万般流连翻过岁月不同侧脸措不及防闯入你的笑颜我曾难自拔于世界之大也沉溺于其中梦话不得真假不做挣扎不惧笑话我曾将青春翻涌成她也曾指尖弹出盛夏心之所动且就随缘去吧逆着光......
  • 模拟赛c题补题
    暴力的写法会导致题目超时所以采用前缀和但是前缀和如果只靠一个数组表示会很绕https://vjudge.net/contest/614523#problem/C暴力代码(过不了)点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintp=2e5+10;ints1[p],s2[p],qq[p];intmain(){ intn,......
  • Vjudge模拟小组
    A-FlagofBerland思路:Code:#include<bits/stdc++.h>usingnamespacestd;constintN=105;intn,m;vector<string>s(N),ss(N);boolcheck(intn,intm){if(n%3)returnfalse;intdivide=n/3;if(s[divide]==s......
  • 初三奥赛模拟测试1--T1回文
    初三奥赛模拟测试1--\(T1\)回文HZOI题意给定一个\(n\timesm\)的,由字符组成的矩阵\(A\),问你由\((1,1)\)开始,点\((i,j)\)只可以往\((i+1,j)\)和\((i,j+1)\)走,走到\((n,m)\)停。记录路径,问由路径上的字符构成的字符串能是回文串......
  • SSK:超级键盘模拟器,调用底层,可模拟所有按键
    SSK-吵架键盘模拟器SuperSimulatorofKeyboard调用系统底层,能够模拟所有键盘操作!本程序结合快Key(QuicKeys智能登录助手)一起使用,能够创造更多奇迹!【下载】点击下载 SSK:超级键盘模拟器:https://files.cnblogs.com/files/BigSystemsView/SSK-%E8%B6%85%E7%BA%A7%E9%94%A......
  • 前端页面使用js模拟ping命令
    letuserIpAddress='';//创建XMLHttpRequest对象varxhr=newXMLHttpRequest();xhr.open('GET','https://api.ipify.org/?format=json');//调用第三方API获取IP地址xhr.onload=function(){if(xhr.status===......
  • 模拟退火学习笔记
    模拟退火,优雅的暴力我认为有必要摘抄一下提单上的简介ZX写的前言:本片适用于模拟退火入门-进阶模拟退火(SA)是一种随机化算法。当一个问题的方案数量极大(甚至是无穷的)而且不是一个单峰函数时,我们常使用模拟退火求解。一般的,很多题都可以用模拟退火水过,在OI界称之[优雅的暴......
  • 初三组合恒等式和二项式定理练习 题解
    A.多项式推柿子:\[\begin{aligned}&\sum\limits_{k=0}^{n}b_{k}(x-t)^{k}\\=&\sum\limits_{k=0}^{n}b_{k}\sum\limits_{i=0}^{k}\binom{k}{i}x^{i}(-t)^{k-i}\\=&\sum\limits_{0\leqslanti\leqslantk\leqslantn}\binom{k}{i}b_{......
  • sql 模拟转账
    CREATEDATABASE`shop`CHARACTERSETutf8COLLATEutf8_general_ciCREATETABLE`account`( `id`INT(3)NOTNULLAUTO_INCREMENT, `name`VARCHAR(10)NOTNULL, `money`DECIMAL(9,2)NOTNULL, PRIMARYKEY(id))ENGINE=INNODBDEFAULTCHARSET=utf8​INSERTIN......