当前位置: 首页 > news >正文

20250405周赛-S

链接

A. 日历

我的:

#include<bits/stdc++.h>
using namespace std;
int n,d[105],ans;
bool check(int x,int y){
	if(x<10){
		if(y<10){
			return x==y;
		}
		else{
			return x==y%10&&x==y/10;
		}
	}
	else{
		if(y<10){
			return y==x%10&&y==x/10;
		}
		else{
			return y/10==x/10&&y%10==x%10&&y%10==y/10;
		}
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		scanf("%d",&d[i]);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=d[i];j++){
			if(check(i,j))ans++;
		}
	}
	cout<<ans;
	return 0;
}

短的:

#include <bits/stdc++.h>
using namespace std;
int ans = 0, n, d, t;
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &d);
        if (i > 9 && i % 11)
            continue;
        t = i % 10;
        if (d >= t)
            ans += 1 + (d >= t * 11);
    }
    cout << ans;
    return 0;
}

 B. 埃尔德什数

我的bfs:

#include <bits/stdc++.h>
using namespace std;
int n, m, x, vis[100005], visid[100005], dist[100005];
vector<int> a[100005], id[100005];
queue<int> q;
int main() {
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int k;
        scanf("%d", &k);
        for (int j = 1; j <= k; j++) {
            scanf("%d", &x);
            a[i].push_back(x);
            id[x].push_back(i);
        }
    }
    memset(dist, 0x3f, sizeof(dist));
    q.push(1);
    vis[1] = 1;
    dist[1] = 0;
    while (q.size()) {
        int x = q.front();
        q.pop();
        for (auto y : id[x]) {
            if (visid[y])
                continue;
            for (auto z : a[y]) {
                if (!vis[z]) {
                    dist[z] = dist[x] + 1;
                    q.push(z);
                    vis[z] = 1;
                }
            }
            visid[y] = 1;
        }
    }
    for (int i = 1; i <= n; i++) {
        if (dist[i] == 0x3f3f3f3f)
            printf("-1\n");
        else
            printf("%d\n", dist[i]);
    }
    return 0;
}

正解:

建虚边虚点(一组一组),答案除二

#include <bits/stdc++.h>
using namespace std;
int n,m,k,v;
vector<int> g[200005];
int main() {
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>k;
		for(int j=0;j<k;j++){
			cin>>v;
			g[--v].push_back(n+i);
			g[n+i].push_back(v);
		}
	}
	queue<int> q;
	q.push(0);
	vector<int> dist(n+m,-2);
	dist[0]=0;
	while(!q.empty()){
		int u=q.front();q.pop();
		for (int i:g[u])
			if(dist[i]+2) ;
			else dist[i]=dist[u]+1,q.push(i);
	}
	for(int i=0;i<n;i++) cout<<dist[i]/2<<'\n';
}

 C. 方格连通性

bfs,没得说

我的:

#include<bits/stdc++.h>
using namespace std;
int n,m,q,mp[2005][2005],fa[4000006];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int fd(int x){
	if(fa[x]==x)return x;
	return fa[x]=fd(fa[x]);
}
void merge(int x,int y){
	int fx=fd(x),fy=fd(y);
	fa[fx]=fy;
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			fa[(i-1)*m+j]=(i-1)*m+j;
		}
	}
	cin>>q;
	for(int i=1;i<=q;i++){
		int op;scanf("%d",&op);
		if(op==1){
			int a,b;
			scanf("%d%d",&a,&b);
			mp[a][b]=1;
			for(int u=0;u<4;u++){
				int nx=a+dx[u],ny=b+dy[u];
				if(mp[nx][ny]){
					if(fd((a-1)*m+b)!=fd((nx-1)*m+ny))merge((a-1)*m+b,(nx-1)*m+ny);
				}
			}
		}
		else{
			int a,b,c,d;
			scanf("%d%d%d%d",&a,&b,&c,&d);
			if(fd((a-1)*m+b)==fd((c-1)*m+d)&&mp[a][b]){
				printf("Yes\n");
			}
			else{
				printf("No\n");
			}
		}
		
	}
	return 0;
}

D. 别样的旅行

水过:O(n^3logn)

#include<bits/stdc++.h>
using namespace std;
int n,m,a[505][505],b[505][505],dist[505][505],vis[505][505];
struct S{
	short x,y;
	int a;
};
bool operator<(S a,S b){
	return a.a>b.a;
}
priority_queue<S>q;
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<m;j++){
			scanf("%d",&a[i][j]);
		}
	}
	for(int i=1;i<n;i++){
		for(int j=1;j<=m;j++){
			scanf("%d",&b[i][j]);
		}
	}
	memset(dist,0x3f,sizeof(dist));
	dist[1][1]=0;
	q.push({1,1,0});
	S x;
	while(!q.empty()){
		x=q.top();q.pop();
		if(vis[x.x][x.y])continue;
		if(x.x==n&&x.y==m)break;
		vis[x.x][x.y]=1;
		if(x.y!=m){
			if(dist[x.x][x.y+1]>dist[x.x][x.y]+a[x.x][x.y]){
				dist[x.x][x.y+1]=dist[x.x][x.y]+a[x.x][x.y];
				q.push({x.x,x.y+1,dist[x.x][x.y+1]});
			}
		}
		if(x.y!=1){
			if(dist[x.x][x.y-1]>dist[x.x][x.y]+a[x.x][x.y-1]){
				dist[x.x][x.y-1]=dist[x.x][x.y]+a[x.x][x.y-1];
				q.push({x.x,x.y-1,dist[x.x][x.y-1]});
			}
		}
		if(x.x!=n){
			if(dist[x.x+1][x.y]>dist[x.x][x.y]+b[x.x][x.y]){
				dist[x.x+1][x.y]=dist[x.x][x.y]+b[x.x][x.y];
				q.push({x.x+1,x.y,dist[x.x+1][x.y]});
			}
		}
		for(int i=1;i<x.x;i++){
			if(dist[x.x-i][x.y]>dist[x.x][x.y]+i+1){
				dist[x.x-i][x.y]=dist[x.x][x.y]+i+1;
				q.push({x.x-i,x.y,dist[x.x-i][x.y]});
			}
		}
	}
	printf("%d",dist[n][m]);
	return 0;
}

正解:少一个O(n^2logn)

最难受的是这个

如果花费是i那么就是到(r-1,c)代价1

那么i+1,即需要记录上一次是不是向上走的,若是代价1,若不是代价2

#include<bits/stdc++.h>
using namespace std;
int n,m,a[505][505],b[505][505],dist[505][505][2],vis[505][505][2];
struct S{
	int x,y,f;
	int a;
};
bool operator<(S a,S b){
	return a.a>b.a;
}
priority_queue<S>q;
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<m;j++){
			scanf("%d",&a[i][j]);
		}
	}
	for(int i=1;i<n;i++){
		for(int j=1;j<=m;j++){
			scanf("%d",&b[i][j]);
		}
	}
	memset(dist,0x3f,sizeof(dist));
	dist[1][1][0]=0;
	q.push({1,1,0,0});
	S x;
	while(!q.empty()){
		x=q.top();q.pop();
		if(vis[x.x][x.y][x.f])continue;
		if(x.x==n&&x.y==m)break;
		vis[x.x][x.y][x.f]=1;
		if(x.y!=m){
			if(dist[x.x][x.y+1][0]>dist[x.x][x.y][x.f]+a[x.x][x.y]){
				dist[x.x][x.y+1][0]=dist[x.x][x.y][x.f]+a[x.x][x.y];
				q.push({x.x,x.y+1,0,dist[x.x][x.y+1][0]});
			}
		}
		if(x.y!=1){
			if(dist[x.x][x.y-1][0]>dist[x.x][x.y][x.f]+a[x.x][x.y-1]){
				dist[x.x][x.y-1][0]=dist[x.x][x.y][x.f]+a[x.x][x.y-1];
				q.push({x.x,x.y-1,0,dist[x.x][x.y-1][0]});
			}
		}
		if(x.x!=n){
			if(dist[x.x+1][x.y][0]>dist[x.x][x.y][x.f]+b[x.x][x.y]){
				dist[x.x+1][x.y][0]=dist[x.x][x.y][x.f]+b[x.x][x.y];
				q.push({x.x+1,x.y,0,dist[x.x+1][x.y][0]});
			}
		}
		if(x.x!=1){
		
			if(dist[x.x-1][x.y][1]>dist[x.x][x.y][x.f]+2-x.f){
				dist[x.x-1][x.y][1]=dist[x.x][x.y][x.f]+2-x.f;
				q.push({x.x-1,x.y,1,dist[x.x-1][x.y][1]});
			}
		}
	}
	printf("%d",min(dist[n][m][0],dist[n][m][1]));
	return 0;
}

E. 逆向边

对于nan:判断是否在同一个连通块即可

对于inf:即存在正环,若有负环反着走就是正环,所以只要有非零环即可

其他的那就是两点距离,和树的处理方法相同

#include<bits/stdc++.h>
using namespace std;
const long long N=1e5+5;
long long n,m,q,idx,vis[N],dist[N],huan[N];
long long head[N],nxt[N*2],v[N*2],e[N*2],tot;
void add(long long a,long long b,long long c){
	nxt[++tot]=head[a];
	v[tot]=b,e[tot]=c;
	head[a]=tot;
}
void dfs(long long x){
	vis[x]=idx;
	for(long long i=head[x];i;i=nxt[i]){
		long long y=v[i],z=e[i];
		if(vis[y]){
			if(dist[y]!=dist[x]+z)huan[idx]=1;//非零环
			continue;
		}
		vis[y]=1;dist[y]=dist[x]+z;
		dfs(y);
	}
}
int main(){
	cin>>n>>m>>q;
	for(long long i=1;i<=m;i++){
		long long a,b,c;
		scanf("%lld%lld%lld",&a,&b,&c);
		add(a,b,c);
		add(b,a,-c);
	}
	for(long long i=1;i<=n;i++){
		if(!vis[i]){
			idx++;
			dfs(i);
		}
	}//连通块划分
	for(long long i=1;i<=q;i++){
		long long x,y;scanf("%lld%lld",&x,&y);
		if(vis[y]!=vis[x])printf("nan\n");
		else if(huan[vis[x]])printf("inf\n");
		else printf("%lld\n",dist[y]-dist[x]);//注意距离
	}
	return 0;
}

相关文章:

  • zookeeper基本概念和核心作用
  • Apache Arrow 使用
  • C++ atomic 原子操作
  • Superset 问题
  • 第十章: 可观测性_《凤凰架构:构建可靠的大型分布式系统》
  • 从数据流程梳理简单GPT模型各部分结构
  • [DP]多重背包
  • 【征程 6】工具链 VP 示例中日志打印解读
  • LeetCode hot 100—删除链表的倒数第N个节点
  • 基于kotlin native的C与kotlin互相调用
  • 数值稳定性
  • Linux开发工具——make/makefile
  • 十大排序-20分钟完成
  • Redis-list类型
  • Spring常见问题复习
  • Web前端页面搭建
  • python logging模块
  • ACM代码模式笔记
  • 学透Spring Boot — 011. 一篇文章学会Spring Test
  • 操作系统——2.4 (管程与死锁的基本概念)