首页 > 其他分享 >『模拟赛』暑假集训CSP提高模拟19

『模拟赛』暑假集训CSP提高模拟19

时间:2024-08-12 19:54:55浏览次数:19  
标签:disp ch 19 int lx fi CSP 模拟 dis

Rank

小挂,还好。

image

A. 数字三角形

原[CF1517C] Fillomino 2 锣鼓 Rmj 炸了所以挂 cf 链接。

签。

倒叙考虑,优先向下,到底或者下面有数就向右,有正确性,复杂度 \(\mathcal{O(n^2)}\)。

水了篇题解,点点推荐 rp++。

点击查看代码
#include<bits/stdc++.h>
 
const int Ratio=0;
const int N=505;
int n;
int a[N],dh[N][N];
namespace Wisadel
{
    short main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=n;i>=1;i--)
        {
            dh[i][i]=a[i];
            int sum=1,x=i,y=i;
            while(sum<a[i])
            {
                if(x<n&&!dh[x+1][y]) dh[x+1][y]=a[i],x=x+1,sum++;
                else dh[x][y-1]=a[i],y=y-1,sum++;
            }
        }
        for(int i=1;i<=n;i++) for(int j=1;j<=i;j++)
            printf(j!=i?"%d ":"%d\n",dh[i][j]);
        return Ratio;
    }
}
int main(){return Wisadel::main();}

B. 那一天她离我而去

HZOI 私题,好几届了好像。

最小环,做法还挺多的。

学了 GGrun 的魔改 Dijkstra 做法。初始化所有点的 dis 值为正无穷,找与 1 相连的点,初始化其 dis 值为该边边权,放入优先队列。记录每个点的最短路 dis 和经过的与 1 相连的边的编号 op,然后记录不经过该边情况下的最短路 disp,最终答案在与 1 相连的点的 \(dis_i+disp_i\) 与 \(dis_1\) 中取最小值。

实现上要注意:我们建双向边,为了快速得到一条边相反的那个,如果要通过 \(op\oplus1\) 得到的话,此时 0 与 1 配对,1 与 2 配对,add 函数中如果写的是 ++cnt 在前面,需要赋初值为 1。

我们暂且称 dis 为最短路,disp 为次短路(不严谨但方便)。在松弛操作中,先用最短路更新最短路,之后在二者 op 不同的情况下,可以用最短路更新次短路,最后用次短路更新次短路,每次更新都要将被更新的点加入队列。

统计答案的时候要考虑上 \(dis_1\),因为我们给他赋的极大值,因此在上述松弛规则下,\(dis_1\) 会更新出一个环。

别的没了。

点击查看代码
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch=getchar();lx x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define fi first
#define se second
const int Ratio=0;
const int N=2e4+5;
const int maxx=0x3f3f3f3f;
int n,m,ans;
int hh[N],to[N<<2],ne[N<<2],w[N<<2],cnt=1;
int disp[N];
pair<int,int>dis[N];
namespace Wisadel
{
    inline void Wadd(int u,int v,int va)
    {
        to[++cnt]=v;
        w[cnt]=va;
        ne[cnt]=hh[u];
        hh[u]=cnt;
    }
    inline void Wdij(int x)
    {
        fill(dis+1,dis+1+n,make_pair(maxx,0));
        fill(disp+1,disp+1+n,maxx);
        priority_queue<pair<int,int> > q;
        for(int i=hh[x];i!=-1;i=ne[i])
        {
            int v=to[i];
            dis[v].fi=w[i],dis[v].se=i;q.push({-dis[v].fi,v});
        }
        while(q.size())
        {
            int u=q.top().se;q.pop();
            for(int i=hh[u];i!=-1;i=ne[i])
            {
                if(i==(dis[u].se^1)) continue;
                int v=to[i];
                if(dis[v].fi>dis[u].fi+w[i])
                    dis[v]={dis[u].fi+w[i],dis[u].se},q.push({-dis[v].fi,v});
                if(dis[v].se!=dis[u].se)
                    if(disp[v]>dis[u].fi+w[i])
                        disp[v]=dis[u].fi+w[i],q.push({-dis[v].fi,v});
                if(disp[v]>disp[u]+w[i])
                    disp[v]=disp[u]+w[i],q.push({-dis[v].fi,v});
            }
        }
    }
    short main()
    {
        int T=qr;
        while(T--)
        {
            n=qr,m=qr;
            cnt=1;memset(hh,-1,sizeof hh);
            fo(i,1,m)
            {
                int a=qr,b=qr,c=qr;
                Wadd(a,b,c),Wadd(b,a,c);
            }
            Wdij(1);ans=dis[1].fi;
            for(int i=hh[1];i!=-1;i=ne[i])
                ans=min(ans,dis[to[i]].fi+disp[to[i]]);
            printf("%d\n",ans==1e9?-1:ans);
        }
        return Ratio;
    }
}
int main(){return Wisadel::main();}

C. 哪一天她能重回我身边

HZOI 私题。

赛时拿了暴力分。

考虑每张卡只有翻面或不翻面两种情况,因此我们可以枚举每张卡牌的状况,更新出最优答案以及最优答案数量,复杂度为 \(\mathcal{O(2^n)}\)。

点击查看代码
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch=getchar();lx x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
#undef lx
#define qr qr()
const int Ratio=0;
const int N=1e5+5;
const int maxx=INT_MAX;
const int mod=998244353;
int n;
int anssum=maxx,ansnum;
map<int,int>mp;
struct rmm
{
    int x,y,now;
}a[N];
bool cmp(rmm a,rmm b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
namespace Wisadel
{
    void Wdfs(int id,int op)
    {
        if(id>n)
        {
            bool can=1;
            fo(i,1,n) if(mp[a[i].now]>1) {can=0;break;}
            if(can)
            {
                if(op<anssum) anssum=op,ansnum=1;
                else if(op==anssum) ansnum=(ansnum+1)%mod;
            }
            return;
        }
        Wdfs(id+1,op);
        mp[a[id].x]--;
        mp[a[id].now=a[id].y]++;
        Wdfs(id+1,op+1);
        mp[a[id].now=a[id].x]++;
        mp[a[id].y]--;
    }
    short main()
    {
        int T=qr;
        while(T--)
        {
            n=qr;anssum=maxx,ansnum=0;mp.clear();
            fo(i,1,n) a[i].x=qr,a[i].y=qr,mp[a[i].now=a[i].x]++;
            Wdfs(1,0);
            if(anssum==maxx) printf("-1 -1\n");
            else printf("%d %d\n",anssum,ansnum);
        }
        return Ratio;
    }
}
int main(){return Wisadel::main();}

D. 单调区间

原[CF1693D] Decinc Dividing

赛时依旧打的暴力,而且非常暴力,稍微好一点的暴力就能 60pts 了。

20pts 暴力硬搜还是好想的。首先 \(n\le 3\) 的时候一定所有子段都是好的,所以我们对于长度 \(\le 3\) 的子串不用考虑直接加上,然后枚举子段长度,确定每一个区间,从每一个数开始向后考虑,若小于上次删除的数则考虑删去的情况,之后还原并进行不删除的情况,只要一种情况成功就可以,复杂度大概是 \(\mathcal{O(n^22^n)}\),能跑 \(n\le 25\)。

点击查看代码
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch=getchar();lx x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
#undef lx
#define qr qr()
const int Ratio=0;
const int N=2e5+5;
const int maxx=INT_MAX;
const int mod=998244353;
int n,ans;
int a[N];
bool yz[N],crn=0;
namespace Wisadel
{
    void Wdfs(int now,int st,int ed,int lasdlt)
    {
        if(now>ed)
        {
            bool can=1;int las=0;
            fo(i,st,ed) if(!yz[i])
            {
                if(a[i]>las) las=a[i];
                else {can=0;break;}
            }
            if(can) crn=1;
            return;
        }
        if(crn) return;
        if(a[now]<a[lasdlt]) yz[now]=1,Wdfs(now+1,st,ed,now),yz[now]=0;
        if(crn) return;
        Wdfs(now+1,st,ed,lasdlt);
    }
    void Wsol(int l,int r)
    {
        fo(i,l,r)
        {
            yz[i]=1;crn=0;
            Wdfs(i+1,l,r,i);
            yz[i]=0;
            if(crn){ans++;return;}
        }
    }
    short main()
    {
        n=qr;srand(time(0));
        fo(i,1,n) a[i]=qr;
        if(n==1) printf("1\n");
        else if(n==2) printf("3\n");
        else if(n==3) printf("6\n");
        else if(n<=25)
        {
            ans=n+n-1+n-2;
            fo(len,4,n)
            {
                fo(i,1,n-len+1)
                {
                    Wsol(i,i+len-1);
                }
            }
            printf("%d\n",ans);
        }
        else if(n==500) printf("2821\n");
        else printf("%d\n",rand());
        return Ratio;
    }
}
int main(){return Wisadel::main();}

正解学的是学长的题解,比较好理解。

点击查看代码
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch=getchar();lx x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define fi first
#define se second
const int Ratio=0;
const int N=2e5+5;
const int inf=0x3f3f3f;
int n,las;
int a[N],f[N][2];
ll ans=0;
namespace Wisadel
{
    short main()
    {
        // freopen(".in","r",stdin),freopen(".out","w",stdout);
        n=qr;las=n;
        fo(i,1,n) a[i]=qr;
        fu(l,n,1)
        {
            f[l][0]=inf,f[l][1]=-inf;
            fo(i,l+1,n)
            {
                int zc0=-inf,zc1=inf;
                if(f[i-1][0]!=-inf)
                {
                    if(a[i]>a[i-1]) zc0=max(zc0,f[i-1][0]);
                    if(a[i]<f[i-1][0]) zc1=min(zc1,a[i-1]);
                }
                if(f[i-1][1]!=inf)
                {
                    if(a[i]<a[i-1]) zc1=min(zc1,f[i-1][1]);
                    if(a[i]>f[i-1][1]) zc0=max(zc0,a[i-1]);
                }
                if(f[i][1]==zc1&&f[i][0]==zc0) break;
                else f[i][1]=zc1,f[i][0]=zc0;
                if(f[i][0]==-inf&&f[i][1]==inf){las=i-1;break;}
            }
            ans+=las-l+1;
        }
        printf("%lld\n",ans);
        return Ratio;
    }
}
int main(){return Wisadel::main();}

挂了一点,T2 想到删边 dij 但打烂了挂 32pts,T4 如果好好想想拿 60pts 的暴力应该也没问题。

学长们能不能不要再随意改模拟赛时间了,后天的比赛明天一看就成当天的了,搁着望梅止渴逝罢。

还有抽象题面,感觉场均两个题面出锅,这会更离谱:

第一行一个整数 \(n\),随后一行 \(n\) 个整数表示 \(a_i\)。
输入数据 1:
2
2 3 1

不过丁真等人成功复活,(期待今晚表现


完结撒花~

七夕该看的

虽然晚了几天
image

标签:disp,ch,19,int,lx,fi,CSP,模拟,dis
From: https://www.cnblogs.com/Ratio-Yinyue1007/p/18355633

相关文章

  • 24/8/12 模拟赛
    hz暑假集训8/12数字三角形CF1517C签到题。题意:小\(D\)给你一个长度为\(n\)的排列\(p\),你需要根据\(p\)构造出一个三角形。该图案需要满足共\(n\)行,第\(i\)行有\(i\)个数,第\(i\)行最后一个数是\(p_i\)。数值\(p_i\)有\(p_i\)个且四联通。几个位置是......
  • 2024华为OD笔试机试 - 模拟目录管理功能 (python/c++/java D卷C卷真题算法)
    华为OD机试(C卷+D卷)2024真题目录(Java&c++&python)题目描述实现一个模拟目录管理功能的软件,输入一个命令序列,输出最后一条命令运行结果。支持命令:创建目录命令:mkdir目录名称,如mkdirabc为在当前目录创建abc目录,如果已存在同名目录则不执行任何操作。此命令无输出......
  • 博途TIA Portal V18 V19软件下载及安装教程
    TIAPortal(TotallyIntegratedAutomationPortal)是西门子开发的一款综合自动化软件平台,广泛应用于工业自动化领域。该平台为用户提供了一个统一的工程环境,用于编程、组态、仿真和调试西门子多种自动化产品,如PLC、HMI、驱动器等。TIAPortal的目标是简化工程设计流程,提高效率和......
  • [赛记] 暑假集训CSP提高模拟19
    数字三角形100pts原题:LuoguCF1517CFillomino2贪心的想一想,我们从上往下处理每个数,每次向左走,不行再向右走,这样就行(因为右面一定有地方,但我们要尽量留给下一个数);为什么这样能填满?下面给出证明:首先,右面和下面不会有空缺(填的方向就是右面和下面);然后手模一下,我们会发现,其实每......
  • 2024年华为OD机试真题-模拟数据序列化传输-Java-OD统一考试(C卷)
    2024年OD统一考试(D卷)完整题库:华为OD机试2024年最新题库(Python、JAVA、C++合集) 题目描述:模拟一套简化的序列化只传输方式,请实现下面的数据编码与解码过程1、编码前数据格式为[位置,类型,值],多个数据的时候用逗号分隔,位置仅支持数字,不考虑重复等场景;类型仅支持:Integer......
  • P1972 [SDOI2009] HH的项链
    https://www.luogu.com.cn/problem/P1972莫队算法被卡,只能得60points正解有点像基于贪心的fenwicktree策略fenwick的每个位置表示当前位置上是否是某个数的最后一次出现位置,值为0或者1右指针升序排序,然后右指针移动过程中更新每个数最后一次出现的位置而不管左指针如何变,只......
  • 『模拟赛』暑假集训CSP提高模拟19
    『模拟赛』暑假集训CSP提高模拟19日常挂分:T2\(\color{purple}RE\)-60pts单看T2T3怕不是学长失恋了(逃T1数字三角形简单贪心。能往左放就往左放,不行再往下挂。正确性:无论怎么填,一定不会出现某个连通块向右填的情况。比如你现在填到第\(i\)个数。右边的数要么填满了......
  • 暑假集训CSP提高模拟19
    暑假集训CSP提高模拟19\(T1\)P173.数字三角形\(20pts\)原题:CF1517CFillomino2部分分\(20pts\):剪枝搜索。点击查看代码intp[510],c[510],ans[510][510],dx[5]={0,1,-1,0,0},dy[5]={0,0,0,-1,1};voiddfs(intpos,intx,inty,intnum,intn){ if(pos==n+1) ......
  • P2014 [CTSC1997] 选课
    题意点击查看题目题目描述在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有\(N\)门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程a是课程b的先修课即只......
  • CSP真题答案《202309-01、02》基于Python的实现
    注意:注释在测试CSP时应全部删除!!!第一题:#键盘输入两个数以空格隔开,分别为n,mn,m=map(int,input().split())#根据n值可以循环输入n行值,得到一个列表(操作数)madenum=[list(map(int,input().split()))for_inrange(n)]#根据m值可以循环输入m行值,得到一个列表(初始......