8-20模拟赛解题报告

不是我没写题目名称,是题目名称就是:T1,T2,T3。。

T1:

题目大意:给出一个长度为(2n)实数数列,你可以把其中(n)个数向上取整,其余向下取整,求操作完后数列和与原来数列和的差的绝对值的最小值。

起初感觉毫无头绪,但在yyh的提醒下,发现也就是求全部(1-a_i-a_j)之和所以,用区间长度除以二减去所有的数就好了。(把所有数的整数部分去掉)

但写完我们就发现了问题,如果输入的数为整数,那向上取整和向下取整的值是一样的,就会造成(1-a_i-a_j)等价于(a_i-a_j),然后,我们就想到了一个很好的解决办法——换个算法。。

其实我们把整个序列分成整数和小数两个部分,分别处理,整数部分就是用来平衡小数部分上下取整的数量问题的。

然后我们可以简化问题,也就是说我们要把整个序列(小数部分)变成(0)(1),两这个数不一定相等,因为有整数可以用来平衡,所以就可以二分一个(1)的数量,然后比较更新答案。时间复杂度为(O(nlongn))

小结:

解题关键:想到简化题意并二分答案。

芝士点:二分答案

这题主要还是靠思维能力。

终于上代码啦:

#include<bits/stdc++.h>
#define re register
using namespace std;
const int N=500005;
int n,Q,num[N],l,r;
double aa[N],a[N],sum[N];
inline bool check(int x,int y,int m){return sum[y]-sum[x-1]-m>0;}
int main()
{
	scanf("%d%d",&n,&Q);
	for(re int i=1;i<=n;i++)
	{
		scanf("%lf",&aa[i]);
		num[i]=num[i-1]+(aa[i]-floor(aa[i])>0);
		sum[i]=sum[i-1]+aa[i]-floor(aa[i]);
	}
	for(re int i=1,x,y,ls;i<=Q;i++)
	{
		scanf("%d%d",&x,&y);
		ls=l=max(0,num[y]-num[x-1]-(y-x+1>>1));
		r=min((y-x+1)>>1,num[y]-num[x-1]);
		for(re int mid=(l+r)>>1;l<r;mid=(l+r)>>1)
		{
			if(check(x,y,mid))l=mid+1;
			else r=mid;
		}
		printf("%.3lf
",min(abs(sum[y]-sum[x-1]-l),l>ls?abs(sum[y]-sum[x-1]-l+1):0x3f3f3f3f));
	}
	return 0;
}

T2

题目大意:给出一棵树与(m)个限制,求任意一个满足此要求的点。限制具体如下:该点到(a_i)(b_i)的距离和不超过(d_i)。如果没有满足条件的点,则输出"NO"。

首先我们可以发现,该点一定是在深度最大的限制的上方,即

[dep[a]-dep[x]+dep[b]-dep[x]le d ]

[Rightarrow dep[x]ge frac{dep[a]+dep[b]-d}{2} ]

其中(x)是我们要求的点,因为此限制深度最大,所以我们最好让(x)在满足这个限制的情况下深度最小,即求最大的(frac{dep[a]+dep[b]-d}{2})

我们就可以在输入时处理出这个节点,然后一边DFS搜索看是否满足所有条件,如果是则输出这个节点,否则输出"NO"。时间复杂度为(O(n))

小结:

解题关键:想到将条件转化,就极容易求解。

芝士点:DFS??

这题和上一题一样,也是主要靠思维

手起,码落:

#include<bits/stdc++.h>
#define re register
using namespace std;
inline int read()
{
	re int x=0,f=1;
	re char ch=getchar();
	for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f*=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
	return x*f;
}
const int N=100005;
struct egde{int v,net;}e[N<<1];
int n,m,fa[N],cnt,hd[N],dep[N],a[N],b[N],d[N],ma,mx,my,dis[N];
inline void add(int v,int u)
{
	e[++cnt].v=v,e[cnt].net=hd[u],hd[u]=cnt;
	e[++cnt].v=u,e[cnt].net=hd[v],hd[v]=cnt;
}
void dfs_first(int u)
{
	for(re int i=hd[u],v;i;i=e[i].net)
	{
		v=e[i].v;
		if(dep[v])continue;
		dep[v]=dep[u]+1,fa[v]=u;
		dfs_first(v);
	}
}
void dfs_second(int u,int fa)
{
	for(re int i=hd[u],v;i;i=e[i].net)
	{
		v=e[i].v;
		if(v==fa)continue;
		dis[v]=dis[u]+1;
		dfs_second(v,u);
	}
}
int main()
{
	n=read(),m=read();
	for(re int i=1;i<n;i++)add(read(),read());
	dep[1]=1,dfs_first(1);
	for(re int i=1,mid;i<=m;i++)
	{
		a[i]=read(),b[i]=read(),d[i]=read();
		mid=(dep[a[i]]+dep[b[i]]-d[i]+1)>>1;
		if(mid>ma)ma=mid,mx=a[i],my=b[i];
	}
	if(dep[mx]>dep[my])swap(mx,my);
	for(;dep[mx]!=ma;)mx=fa[mx];
	dfs_second(mx,0);
	for(re int i=1;i<=m;i++)
		if(dis[a[i]]+dis[b[i]]>d[i])return puts("NO"),0;
	return printf("%d",mx),0;
}

T3

不会写,以后有时间来补,咕咕咕~

原文地址:https://www.cnblogs.com/jkzcr01-QAQ/p/13574115.html