高一普及组模拟赛2-2021.4.23

又是一个美妙的周六……

上午第五节课实验系列校内放假我们还得学焚化课……可恶

四道题目三个半小时

A. 循环

B. 漫步

C. 穿越

D. 结队

赛时得分: 380/400

赛时排行: 2

 

吸取上次的教训先都看了一遍

T1好像就是一个简简单单模拟题?放着看T2

T2也是模拟?

T3是个深搜地图题目?

T4……老师您确定T3T4没反过来???

先切T1

这没啥好说的硬判循环节完事

好像有个奇妙的性质?只用看最后两位就行?

20分钟切了

#include<cstdio>
#include<cstring>
#include<string>
#define WR WinterRain
using namespace std;
const int WR=1001,mod=100;
int n;
bool vis[WR];
int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
int main(){
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    memset(vis,false,sizeof(vis));
    n=read();
    int tmp=n;
    n%=100;
    while(1==1){
        if(vis[n]) break;//这块稍微卡了一下下
        vis[n]=true;//顺序不能乱
        printf("%d ",n);
        n=(tmp*n)%mod;
    }
    printf("%d",n);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

预估的分:100

然后看T2

 

一开始有模拟的想法

然鹅后来发现不用,只需要从后往前找降序队列就行了

避免寄掉开了long long(好像不用?)

//芜湖肯定不能打模拟(
//应该是找最低速度个数? 可以把最低速度变成0然后相当于往上面撞,撞到就停下来
//样例是可行的但鬼都知道样例...乱搞都能过
//先看看
//------------------------------------------------------------------------
//update:果然做法伪了...
//如果i在j前面,而且i的速度比j的大
//他们也根本不会相遇啊喂
//亏我写了sort
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define WR WinterRain
using namespace std;
const long long WR=1001000;
long long n,mrg;//需要long long么? 我也不知道
long long d[WR],v[WR];
long long ans=0;
long long read(){
    long long s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
int main(){
    freopen("jog.in","r",stdin);
    freopen("jog.out","w",stdout);
    n=read();
    for(long long i=1;i<=n;i++) d[i]=read(),v[i]=read();
    mrg=v[n];
    for(long long i=n;i>=1;i--){
        if(v[i]>mrg) continue;//必须严格大于
        else ans++,mrg=v[i];
    }
    printf("%lld",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

 

然后看着T3就头疼,开T4

???一开始先想了正向硬暴力

分析复杂度n2 显然过不了(但是后来证明能过,数据太水)

然后发现可以先筛质数,找出大于等于p的然后向上乘,找出每个质数在 [l,r] 中的倍数

然后硬合并,15ms过了

//真的有人看不出来C,D换了位置么...
//并查集裸题
//啊不,这是数学题目啊
//-------------------------------
//update 19:39
//貌似是可以先搞出质数再乘?乘出范围l->r区间内的数直接合并完事...
//可恶,浪费我半小时
//我还开了vector...无语住了
#include<cstdio>
#include<cstring>
#include<string>
#define WR WinterRain
using namespace std;
const int WR=50010;
struct Gang{
    int num,pnt;
    //pnt是指向
}a[WR];
int l,r,p;
int pri[WR],cnt,phi[WR];
int num=0,prime[WR],ans=0;
bool flag[WR];
int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
void Euler(int tot){
    memset(flag,true,sizeof(flag));
    flag[1]=false;
    for(int i=2;i<=tot;i++){
        if(flag[i]) pri[++cnt]=i;
         for(int j=1;j<=cnt&&i*pri[j]<=tot;j++){
            flag[i*pri[j]]=false;
            if(i%pri[j]==0) break;
        }
    }
}
int getfa(int x){
    if(a[x].pnt==x) return x;
    return a[x].pnt=getfa(a[x].pnt);
}
void dalaomerge(int x,int y){
    int fax=getfa(x),fay=getfa(y);
    a[fax].num+=a[fay].num;
    a[fay].num=0;
    a[fay].pnt=fax;
}
int main(){
    freopen("merge.in","r",stdin);
    freopen("merge.out","w",stdout);
    l=read(),r=read(),p=read();
    for(int i=l;i<=r;i++)
        a[i].num=1,a[i].pnt=i;
    Euler(r);//看我欧拉筛
    for(int i=1;i<=cnt;i++)
        if(pri[i]>=p) prime[++num]=pri[i];
    for(int i=1;i<=num;i++){
        int st,ed;
        if(l/prime[i]*prime[i]==l) st=l/prime[i];
        else st=l/prime[i]+1;
        ed=r/prime[i];
        //printf("%d %d\n",st,ed);
        for(int j=st+1;j<=ed;j++){
            if(j*prime[i]<l) continue;
            if(j*prime[i]>r) break;
            dalaomerge(st*prime[i],j*prime[i]);
            //printf("%d ",j);
        }
        //printf("\n");
    }
    for(int i=l;i<=r;i++){
        //printf("%d %d %d\n",i,a[i].num,a[i].pnt);
        if(a[i].num) ans++;
    }
    printf("%d",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

 

此刻剩下一个小时30分钟开T3

赛时敲了80分……代码里有分析

//恶心人的大BFS
//怎么还得加时间戳??????
//我看看写不写的完...毕竟是还有一个半小时
//拿什么部分分,我今天不成功则成仁
//---------------------------------------
//update 20:37 我的天居然还要套Dijkstra
//我天真了
//幸好我没先开第三题
//---------------------------------------
//update 21:36 好像过了样例
//关于居然可以等野兽睡着再走这档子事
//关于居然可以一动不动这档子事
//关于传送需要两个单位时间这档子事
//出题人还算有点良心不用判无解
//传送门不一定要传送...寄(话说我之前好像做过类似的题目)
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#define WR WinterRain
using namespace std;
const long long WR=550;
long long dx[4]={0,0,-1,1},dy[4]={1,-1,0,0};
long long n,m,r,b;
long long rain[WR][WR];//非常合理
long long mp[WR][WR],dis[WR][WR];//dis存的是时间然鹅既然是dijkstra...入乡随俗(bushi)
long long wke[WR][WR],slp[WR][WR];//存野兽先辈出没的时间
vector<pair<long long,long long> >tp;//存传送门
long long read(){
    long long s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
bool judge(long long x,long long y){
    if(x<=n&&x>=1&&y<=m&&y>=1&&mp[x][y]!=1) return true;
    else return false;
}
void dijkstra(){
    queue<pair<long long,long long> >q;//是什么促使我把queue打成了query???
    dis[1][1]=0;
    q.push({1,1});
    while(!q.empty()){
        long long x=q.front().first,y=q.front().second;
        q.pop();
        for(long long i=0;i<4;i++){
            long long posx=x+dx[i],posy=y+dy[i];
            if(judge(posx,posy)){
                if(mp[posx][posy]==0){//这一块是空地可以通行
                    if(dis[x][y]+1<rain[posx][posy]&&dis[posx][posy]>dis[x][y]+1){
                        dis[posx][posy]=dis[x][y]+1;
                        q.push({posx,posy});
                    }
                }
                if(mp[posx][posy]==2){//野兽先辈出没(bushi
                    if(dis[x][y]+1<rain[posx][posy]){//好像没下雨?
                        if(dis[x][y]+1>=wke[posx][posy]&&dis[x][y]+1<=slp[posx][posy]){//这里有问题???
                            if(dis[posx][posy]>slp[posx][posy]+1&&slp[posx][posy]+1<rain[posx][posy]){
                                //我天太细节了
                                //这都行???dis可以大于下雨时间必须要用slp???
                                dis[posx][posy]=slp[posx][posy]+1;//能过而且不会下雨...
                                //我可以等...
                                q.push({posx,posy});//我真的只听说过带时间戳的莫队没听说过带时间戳的dijkstra...
                            }
                        }else{
                            if(dis[posx][posy]>dis[x][y]+1){//如果野兽先辈没醒就直接更新
                                dis[posx][posy]=dis[x][y]+1;
                                q.push({posx,posy});
                            }
                        }
                    }
                }
                if(mp[posx][posy]==3){//传送门永远的噩梦...
                    if(dis[x][y]+1<rain[posx][posy]){
                        if(dis[posx][posy]>dis[x][y]+1){
                            dis[posx][posy]=dis[x][y]+1;//我不过,我就是不过欸嘿嘿气死你
                            q.push({posx,posy});//不是...其实就是可以不过,有可能更优
                        }else{//比如我在终点前有一个传送门然后你又传送回去了...
                            for(long long j=0;j<tp.size();j++){//枚举每一个传送门吧
                                //我记得我做过一个相配对的...和这个不相上下恶心人
                                long long tpx=tp[j].first,tpy=tp[j].second;//WTF我前面用了i了
                                if(dis[x][y]+3<rain[tpx][tpy]&&dis[x][y]+3<dis[tpx][tpy]){
                                    dis[tpx][tpy]=dis[x][y]+3;
                                    q.push({tpx,tpy});
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
int main(){
    freopen("cross.in","r",stdin);
    freopen("cross.out","w",stdout);
    memset(dis,0x3f,sizeof(dis));
    memset(rain,0x3f,sizeof(rain));
    n=read(),m=read();
    for(long long i=1;i<=n;i++){
        for(long long j=1;j<=m;j++){
            mp[i][j]=read();
            if(mp[i][j]==3) tp.push_back({i,j});
        }
    }
    r=read();
    for(long long i=1;i<=r;i++){
        long long t=read(),p=read();
        for(long long j=1;j<=p;j++){
            long long x=read(),y=read();
            rain[x][y]=min(t,rain[x][y]);//还有可能多次冲刷...出题人你真有****
        }
    }
    b=read();//b代表了beast!下北泽(bushi)
    for(long long i=1;i<=b;i++){
        long long awake=read(),sleep=read(),x=read(),y=read();
        wke[x][y]=awake;
        slp[x][y]=sleep;//玩阴的是吧
    }
    dijkstra();
    printf("%lld",dis[n][m]);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

然后不知道为啥挂了?看看题解……

然后把我的干上去……发现???过了???

#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#define WR WinterRain
using namespace std;
const long long WR=1050;
long long dx[4]={0,0,-1,1},dy[4]={1,-1,0,0};
long long n,m,r,b;
long long rain[WR][WR];//非常合理
long long mp[WR][WR],dis[WR][WR];//dis存的是时间然鹅既然是dijkstra...入乡随俗(bushi)
long long wke[WR][WR],slp[WR][WR];//存野兽先辈出没的时间
vector<pair<long long,long long> >tp;//存传送门
long long read(){
    long long s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
bool judge(long long x,long long y){
    if(x<=n&&x>=1&&y<=m&&y>=1&&mp[x][y]!=1) return true;
    else return false;
}
void bfs(){
    for(int i=1;i<=n;i++)
        for(int k=1;k<=m;k++)
            dis[i][k]=1e9+7;
    queue<pair<int,int>>q;
    dis[1][1]=0;
    q.push({1,1});
    while(!q.empty()){
        auto p = q.front();q.pop();
        int x = p.first, y = p.second;
        for(int i=0;i<4;i++){
            int posx = x + dx[i],posy = y +dy[i];
            if(judge(posx,posy)&&mp[posx][posy]!=1){///可走
                if(mp[posx][posy]==0){///空地
                    if(dis[x][y]+1<rain[posx][posy]&&dis[posx][posy]>dis[x][y]+1){
                        dis[posx][posy]=dis[x][y]+1;
                        q.push({posx,posy});
                    }
                }
                else if(mp[posx][posy]==2){///野兽fuck
                    if(dis[x][y]+1<rain[posx][posy]){///大雨fuck
                        int f=0;
                        if(dis[x][y]+1>=wke[posx][posy]&&dis[x][y]+1<=slp[posx][posy]) f=1;
                        if(f){///不可以过去
                            if(dis[posx][posy]>slp[posx][posy]+1&&slp[posx][posy]+1<rain[posx][posy]){
                                dis[posx][posy]=slp[posx][posy]+1;
                                q.push({posx,posy});
                            }
                        }
                        else{
                            if(dis[posx][posy]>dis[x][y]+1){
                                dis[posx][posy]=dis[x][y]+1;
                                q.push({posx,posy});
                            }
                        }
                    }
                }
                else if(mp[posx][posy]==3){
                    ///不传送
                    if(dis[x][y]+1<rain[posx][posy]&&dis[posx][posy]>dis[x][y]+1){///当前不会被冲刷
                        dis[posx][posy]=dis[x][y]+1;
                        q.push({posx,posy});
                    }
                    ///传送
                    if(dis[x][y]+1<rain[posx][posy]){
                        for(int j=0;j<tp.size();j++){
                            int tpx=tp[j].first,tpy=tp[j].second;
                            if(dis[x][y]+3<rain[tpx][tpy]&&dis[x][y]+3<dis[tpx][tpy]){
                                dis[tpx][tpy]=dis[x][y]+3;
                                q.push({tpx,tpy});
                            }
                        }
                    }
                }
            }
        }
    }
}
int main(){
    freopen("cross.in","r",stdin);
    freopen("cross.out","w",stdout);
    n=read();m=read();
    for(int i=1;i<=n;i++)
        for(int k=1;k<=m;k++){
            scanf("%d",&mp[i][k]);
            if(mp[i][k]==3) tp.push_back({i,k});///传送地带
            rain[i][k]=1e9+7;///时间初始化1e9+7
        }
    int p=read();
    for(int i=1;i<=p;i++){///大雨冲刷时间r
        int tt;scanf("%d",&tt);
        int a;scanf("%d",&a);
        for(int k=1;k<=a;k++){
            int x,y;scanf("%d%d",&x,&y);
            if(tt<rain[x][y]) rain[x][y]=tt;
        }
    }
    p=read();
    for(int i=1;i<=p;i++){
        int t1,t2,x,y;
        scanf("%d%d%d%d",&t1,&t2,&x,&y);
        wke[x][y]=t1;
        slp[x][y]=t2;
    }
    bfs();
    printf("%lld\n",dis[n][m]);
    return 0;
}

看上去没什么区别?这。。。可恶

总结

这次做题顺序还对。。。没出现别的什么情况

可惜拿了rank2,可恶

%%%gtm大佬太巨了把我吊着打

posted @ 2022-04-24 09:02  冬天丶的雨  阅读(46)  评论(0编辑  收藏  举报
Live2D