5.13 模拟赛题解

T1 P4304 [TJOI2013] 攻击装置

快进到 HZOI2023 超越 HZOI2020 (人均场切了紫)

考虑将棋盘黑白染色成这个样子

image

容易发现相同颜色的点直接一定没有冲突,满足二分图的性质,需要求出最小点覆盖,所以直接按冲突建好双向边,从 \(1\)\(n^2\) 节点跑最大匹配即可。

设求出的最大匹配为 \(ans\),因为是每个点都跑了一遍,所以真正的最大匹配为 \(\frac{ans}{2}\),也是最小点覆盖,设所有合法点数为 \(num\),最终的答案就是 \(num-\frac{ans}{2}\)

其实这题正解应该是网络流,二分图理论复杂度不对,但是这是古早省选题,数据比较水,且卡不满,所以就放过了二分图。(是道水紫,只是数据太弱)

#include<bits/stdc++.h>
inline int read(){
    int x=0,f=1;char ch=getchar();
    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;
}
const int N=205;
int a[N][N],id[N][N],cnt,vis[N*N*2],head[N*N*2],maxn,match[N*N*2],n,ans;
int x[9]={0,-1,-2,+1,+2,-1,-2,+1,+2},y[9]={0,-2,-1,-2,-1,+2,+1,+2,+1};
struct EDGE{int v,next;}e[(N*N)<<5];
inline void add(int u,int v){e[++cnt]={v,head[u]},head[u]=cnt;}
inline bool dfs(int x,int round){
    for(int i=head[x];i;i=e[i].next){
        int y=e[i].v;
        if(vis[y]==round)continue;
        vis[y]=round;
        if(match[y]==0||dfs(match[y],round)){
            match[y]=x;return true;
        }
    }
    return false;
}
int main(){
    // freopen("attack.in","r",stdin);freopen("attack.out","w",stdout);
    std::ios::sync_with_stdio(0);std::cin.tie(0),std::cout.tie(0);
    n=read();maxn=n*n;
    int _zc=0;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            char ch=getchar();
            while(ch!='0'&&ch!='1')ch=getchar();
            if(ch=='1')a[i][j]=1;else _zc++;
        	id[i][j]=++cnt;
        }
    }cnt=0;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            if(!a[i][j]){
                for(int w=1;w<=8;++w){
                    int _x=i+x[w],_y=j+y[w];
                    if(_x>=1&&_x<=n&&_y>=1&&_y<=n&&(!a[_x][_y])){
                        add(id[i][j],id[_x][_y]);
                        add(id[_x][_y],id[i][j]);
                    }
                }
            }
        }
    }
	for(int i=1;i<=maxn;++i){
		if(dfs(i,i))ans++;
	}
	std::cout<<_zc-ans/2<<'\n';
}

T2 循环

有啥深意吗,深意就是剩余系内乘法封闭了,所以循环节数量是 \(O(n)\)

#include<bits/stdc++.h>
inline int read(){
    int x=0,f=1;char ch=getchar();
    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;
}
std::unordered_map<int,int> t;
int main(){
	freopen("number.in","r",stdin);freopen("number.out","w",stdout);
    int x=read(),last=1;
    while(1){
    	int v=last*x%100;
        if(t[v]){std::cout<<v<<' ';exit(0);}
        else {
            t[v]=1;last=v;
            std::cout<<v<<' ';
        }
    }
}

T3 漫步

没啥深意,都给好顺序了,跑一遍发现如果当前速度比之前所有速度都小于等于,那么就会多一组,本质上是一个单调栈的过程。

#include<bits/stdc++.h>
inline int read(){
    int x=0,f=1;char ch=getchar();
    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;
}
const int N=1e5+10;
int v[N],d[N],n,f1[N],f2[N],f[N];
int main(){
    freopen("jog.in","r",stdin);freopen("jog.out","w",stdout);
    std::ios::sync_with_stdio(0);std::cin.tie(0);std::cout.tie(0);
    n=read();
    for(int i=1;i<=n;++i){d[i]=read(),v[i]=read();}
    int ans=1;f[n]=v[n];
   	for(int i=n-1;i;--i){
        if(v[i]>f[i+1]){
            f[i]=f[i+1];
        }else{
            f[i]=v[i];ans++;
        }
	}
    std::cout<<ans<<'\n';
}

T4 穿越

直接设 \(f_{k,i,j}\) 表示到第 \(k\) 个时间,能否到达 \((i,j)\) 位置。

直接判断是否合法加转移就行。

理论时间复杂度 \(O(t\cdot nm)\),我知道这肯定过不了,但wtcl,不会别的。

还能一堆乱搞,且都能卡,没啥意思。

#include<bits/stdc++.h>
inline int read(){
    int x=0,f=1;char ch=getchar();
    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;
}
const int N=305;
int a[N][N],n,m;
bool f[8895][N][N];
struct TIME{int l,r,s;}t[N][N];
std::vector<std::pair<int,int>> c;
int x[6]={0,1,-1,0,0,0};
int y[6]={0,0,0,1,-1,0};
inline bool safe(int k,int i,int j){
	if(a[i][j]==1)return false;
	if(t[i][j].s&&k>=t[i][j].s)return false;
	if(a[i][j]==2&&k>=t[i][j].l&&k<=t[i][j].r)return false;
	return true;
}
int main(){
    freopen("cross.in","r",stdin);freopen("cross.out","w",stdout);
    std::ios::sync_with_stdio(0);std::cin.tie(0);std::cout.tie(0);
    n=read(),m=read();
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
        	a[i][j]=read();
        	if(a[i][j]==3){c.push_back({i,j});}
        }
    }
    int zc=read();
    for(int i=1;i<=zc;++i){
        int _t=read(),p=read();
        for(int j=1;j<=p;++j){
            int x=read(),y=read();
            if(!t[x][y].s)t[x][y].s=_t;
            else t[x][y].s=std::min(t[x][y].s,_t);
        }
    }
    zc=read();
    for(int i=1;i<=zc;++i){
        int _t1=read(),_t2=read();
        int x=read(),y=read();
        t[x][y].l=_t1,t[x][y].r=_t2;
    }
    f[0][1][1]=1;
    for(int k=0;k<=8895;++k){
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j){
    			if(!f[k][i][j])continue;
    			if(i==n&&j==m&&f[k][i][j]){
    				std::cout<<k<<'\n';exit(0);
				}
				for(int w=1;w<=5;++w){
					int _i=i+x[w],_j=j+y[w];
					if(safe(k+1,_i,_j))f[k+1][_i][_j]=1;
				}
				if(a[i][j]==3){
					for(auto it:c){
						int _x=it.first,_y=it.second;
						if(_x==i&&_y==j)continue;
						if(safe(k+2,_x,_y)&&safe(k+1,_x,_y)){
							f[k+2][_x][_y]=1;
						}
					}
				}
			}
		}
	}
}

T5 结队

直接埃氏筛,在筛的过程中用筛到的素数枚举系数,然后根据这个建出并查集,最后找一遍即可,时间复杂度大概是 \(O(n\log n)\) 吧,跑挺快,不过这个没想到是真不应该。



#include<bits/stdc++.h>
const int N=5e5+100,maxn=5e5+10;
int l,r,P,fa[N],pr[N],tot;
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
bool vis[N];
inline void work(int n){
    for(int i=2;i<=n;++i){
        if(!vis[i])pr[++tot]=i;
        int base=0;
        if(!vis[i]){
            for(int j=1;j<=maxn&&j*i<=r;++j){
                int zc=j*i;
                if(zc>=l&&(!base))base=find(zc);
                vis[zc]=1;
                if(i>=P)fa[find(zc)]=base;
            }
        }
    }
}
int ans[N];
int main(){
     freopen("merge.in","r",stdin);freopen("merge.out","w",stdout);
    std::cin>>l>>r>>P;
    for(int i=1;i<=r;++i)fa[i]=i;
    work(r);tot=0;
    for(int i=l;i<=r;++i){
        if(!ans[find(i)])tot++,ans[find(i)]=1;
    }
    std::cout<<tot<<'\n';
}

male,这题好像是我这场比赛唯一有点收获的地方

posted @ 2024-05-13 18:13  Ishar-zdl  阅读(46)  评论(3)    收藏  举报