开始: 2023-08-12 08:20:00

0812算法入门(2)期末测试

结束: 2023-08-12 11:00:00
当前  2025-01-24 18:02:30  类型: IOI  状态: 已经结束 

T1移山填海

典型的遍历填充算法!我们考虑搜索到一个区间,就开始填充操作!这里面需要开一个数组存下你的耗费,最后sort后输出即可!

考察 bfs/dfs+排序!

dfs遍历部分

void dfs(int x,int y ){
	vis[x][y]=1;
	if(mp[x][y]>0) s+=mp[x][y]*2;
	else s-=mp[x][y];
	for(int i=0;i<4;i++){
		int tx=x+nx[i],ty=y+ny[i];
		if(tx<1||ty<1||tx>n||ty>m||vis[tx][ty]||mp[tx][ty]==0) continue;
		dfs(tx,ty);
	}
	return;
}

主函数部分

	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(mp[i][j]!=0 && !vis[i][j]){
				s=0;
				dfs(i,j);
				mj[++cnt]=s;
			}	

最后sort输出即可!!


T3 砍树

因为是45度,所以树最后的高度,就是a[i]-a[i-1]的距离,同理右边看过来也是这样的,所以我们左边处理一遍,右边处理一遍即可

考察排序+分步骤处理问题

时间复杂度最大的是由sort提供的,也就是n(logn)

给出的代码是中间一起处理的,两头额外处理,左边处理一遍右边处理一遍,代码上可能更简单

	sort(a+1,a+n+1,cmp);
	if(a[2].a-a[1].a<a[1].b)
	ans+=a[1].b-a[2].a+a[1].a;
	int minx;
	for(int i=2;i<n;i++)
	{
		minx=min(a[i].a-a[i-1].a,a[i+1].a-a[i].a);
		if(a[i].b>minx)
		ans+=a[i].b-minx;
	}
	if(a[n].a-a[n-1].a<a[n].b)
	ans+=a[n].b-a[n].a+a[n-1].a;

T4 消灭扫雷团伙

裸的并查集,并查集做完以后,利用桶把每个团伙给统计一下!代码就不给出了


T5 强壮网络

处理之前,先把费用重新计算一下,然后放入结构体数组,接下来就是最小生成树了!

下面给出的处理价值的代码,价值处理完,那就是并查集了!

  for(int i=1; i<=m; i++)
  {
    int  val,op;
    G[i].u=read();
    G[i].v=read();
    val=read();
    op=read();
    if(op)
      G[i].w=(val+1)/2;
    else
      G[i].w=val*2;
  }

T6和谐数

利用bfs拓展数字,和电梯一题差不多!注意特判防止越界

	for(int i=1;i<=9;i++)
		q.push(i);
	int cnt=0;
	while(!q.empty()){
		long long p1=q.front();
		q.pop();
		cnt++;
		if(cnt==n){
			cout<<p1;
			break;
		}
		for(int i=-1;i<=1;i++){
			long long p2=p1%10+i;
			if(p2>=0&&p2<=9){
				q.push(p1*10+p2);
			}
		}
	}