2024/2/6

文章介绍了三道编程题目,分别涉及计算达到特定位数的最小正整数的二分查找方法,使用并查集解决公路修复中最早通车时间的问题,以及使用二分搜索策略凑出最多卡牌套数。展示了如何运用IT技术中的算法和数据结构解决问题。
摘要由CSDN通过智能技术生成

P2759 奇怪的函数

题目描述

使得 x^x 达到或超过 n 位数字的最小正整数x 是多少?

输入格式

一个正整数 n。

输出格式

使得 x^x 达到 n 位数字的最小正整数 x。

一道二分题目

首先n^n是一定会大于等于n位的

所以右端点就确定了

所以区间为【1,n】

比较难的就是怎么表示位数,百度发现c++自带log10函数所以可以用x*log10(x)=log10(x*x)来表示位数

完整代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
	long long n,x,r,l;
	cin>>n;
	l=1,r=n+10;
	while(l<r)
	{
		long long mid=(l+r)/2;
		long long sum=(mid*log10(1.0*mid))+1;
		if(sum<n)
		{
			l=mid+1;
		}
		else
		{
			r=mid;
		}
	}
	cout<<l<<endl;
	return 0;
}

P1111 修复公路

题目背景

A 地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。

题目描述

给出 A 地区的村庄数 N,和公路数 M,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)。

输入格式

第 11 行两个正整数 N,M。

下面 M 行,每行 33 个正整数 x,y,t,告诉你这条公路连着x,y 两个村庄,在时间t时能修复完成这条公路。

输出格式

如果全部公路修复完毕仍然存在两个村庄无法通车,则输出−1,否则输出最早什么时候任意两个村庄能够通车。

这题考察并查集

要注意路是同时进行修复的

所以我们可以按修路时间来排序,然后把用时短的合并在一起,当所有村庄都被连通时输出目前的最大时间

如果按时间排序的话,对应连通的路线也要跟着变,此时可以用结构体来处理

完整代码

#include<bits/stdc++.h>
using namespace std;
struct road
{
	int x;
	int y;
	int t;
}a[100005];
int fa[100005],n,m;
bool op(road s,road h)
{
	return s.t<h.t;
}
void iint()
{
	for(int i=1;i<=n;i++)
	{
		fa[i]=i;
	}
}
int find(int u)
{
	if(fa[u]==u)
	{
		return u;
	}
	else
	{
		return fa[u]=find(fa[u]);
	}
}
void join(int v,int u)
{
	u=find(u);
	v=find(v);
	if(u==v)
	{
		return;
	}
	fa[v]=u;
}
bool judge()
{
   int sum=0;
   for(int i=1;i<=n;i++)
   {
   	if(fa[i]==i)
   	{
   		sum++;
    }
    if(sum==2)
    {
    	return 0;
	}
   }
   return 1;
}
int main()
{
	cin>>n>>m;
	iint();
	for(int i=1;i<=m;i++)
	{
		cin>>a[i].x>>a[i].y>>a[i].t;
	}
	sort(a+1,a+m+1,op);
	for(int i=1;i<=m;i++)
	{
		join(a[i].x,a[i].y);
		if(judge())
		{
			cout<<a[i].t;
			return 0;
		}
	}
	cout<<-1<<endl;
	return 0;
}

P8800 [蓝桥杯 2022 国 B] 卡牌

题目描述

这天,小明在整理他的卡牌。

他一共有 n 种卡牌,第 i 种卡牌上印有正整数数 i(i∈[1,n]), 且第 i 种卡牌现有 ai​ 张。

而如果有 n 张卡牌,其中每种卡牌各一张,那么这 n 张卡牌可以被称为一套牌。小明为了凑出尽可能多套牌,拿出了 m 张空白牌, 他可以在上面写上数 i,将其当做第 i 种牌来凑出套牌。然而小明觉得手写的牌不太美观,决定第 i 种牌最多手写 bi​ 张。

请问小明最多能凑出多少套牌?

输入格式

输入共 3 行,第一行为两个正整数 n,m 。

第二行为 n 个正整数 1,2,…,a1​,a2​,…,an​ 。

第三行为 n 个正整数 1,2,…,b1​,b2​,…,bn​ 。

输出格式

一行,一个整数表示答案。

二分;每次搜索能够凑出来的最大牌数,

这个最大牌套数需要满足每种卡片都足够

所以左区间为初始的ai,右区间为ai+bi;

这个mid数需要满足mid-ai<bi,否则不满足,区间改变

然后所有mid-ai(即需要手写的值加起来)少于等于m张牌

如果mid数满足就要使右边缩小为mid,继续二分,

不满足则使左边增大为mid,继续二分;

完整代码 

#include<bits/stdc++.h>
using namespace std;
long long n,m;
long long a[200005],b[200005];
bool check(int x)
{
	long long sum=0;
	for(int i=1;i<=n;i++)
	{
		if(x-a[i]>b[i])
		{
			return false;
		}
		sum+=max(x-a[i], (long long)0);
	}
	if(sum<=m)
	{
		return true;
	}
	else
	{
		return false;
	}
}
int main()
{
	cin>>n>>m;
	for(long long i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(long long i=1;i<=n;i++)
	{
		cin>>b[i];
	}
	long long l=1,r=1e9;
	while(l+1<r)
	{
		long long mid=(l+r)/2;
		if(check(mid))
		{
			l=mid;
		}
		else
		{
			r=mid;
		}
	}
	if(check(r)) 
	{
	  cout<<r;
	}
	else
	{
		cout<<l;
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值