杭电多校总结2021-08-10

1003 Fall with Trees

Problem Description
Fall wants to draw a perfect binary tree.

We first stipulate that all nodes in the tree with the same depth also
have the same y-coordinate in the plane. Define nodes with the same
depth to be nodes at the same level, then the perfect binary tree has
four properties.

  • It is a full binary tree.
  • The difference between the y-coordinates of two nodes at each adjacent level is a constant.
  • The difference between the x-coordinates of two adjacent nodes at the same level is constant.
  • The x-coordinate of each node is the average of the x-coordinates of its sons.

Fall has drawn the root node and its left and right sons of this
binary tree. Now Fall intends to draw a total of k levels and cut the
binary tree down and paste it on the wall afterwards, so he wants to
know what is the area of the convex hull of all nodes of this perfect
binary tree.

Input
The input consists of multiple test cases.

The first line contains an integer T (T≤2×105) – the number of test
cases.

For each test case:

In the first line, there is an integer k (2≤k≤104).

In the second line, there are six integers
xroot,yroot,xlson,ylson,xrson,yrson∈[−104,104] ,which represent the
coordinates of the root node and its sons.

It is guaranteed that all the coordinates meet the conditions of the
question, which means:

  • xlson+xrson=2×xroot
  • ylson=yrson
  • yroot>ylson,xlson<xrson

Output
For each test case, output a real number representing the answer, with three decimal places.

#include<iostream>
#include<cmath>
using namespace std;

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int k;
		scanf("%d",&k);
		double xt,yt,xl,yl,xr,yr;
		scanf("%lf%lf%lf%lf%lf%lf",&xt,&yt,&xl,&yl,&xr,&yr);
		double h=abs(yl-yt);
		double a=xr-xl;
		double res=a*h/2*(4*(k-2)+3*pow(0.5,k-2)-2);
		printf("%.3lf\n",res);
	}
	return 0;
}

1005 Link with EQ

Problem Description
We often say that details can reflect the level of one’s EQ. For
example, at BIT, when students study in classrooms (such as A105 in
the General Teaching Building) or on long tables in the library, it is
often embarrassing and uncomfortable (and occasionally smelly) if
another student suddenly sits next to them, which we call low EQ
behavior.

Now, there is a long table containing n seats, and the BIT students
will choose their seats in the following way in order to avoid low EQ
behavior as much as possible.

  • If the whole table is empty, randomly choose a position to sit.
  • Otherwise, choose a position whose shortest distance to other students is maximized. If there are more than one, randomly choose one
    of them with equal possibility.

When the farthest distance is 1 (i.e., he will sit next to a classmate
anyway), students will sit at a different table to avoid low EQ
behavior, and then we will call the table full.

Now, Link wants to know the expected number of people seated in the
table when the table is full.

Input
The input consists of multiple test cases.

The first line contains an integer T (1≤T≤105) – the number of test
cases.

For each testcase, there is only one integer n (1≤n≤106) in a single
line, which is the length of the table.

Output
For each testcase, output the answer modulo 109+7.

You may find the way to modulo a rational number in Problem 1006.

大意:
有 n 个座位,起初第一个人会随机挑选一个位置坐下,后来的人会挑一个离最近的人最远的位置坐下,当无论挑什么位置旁边( + 1 或 − 1 的位置)都已经坐了人的话。
在这里插入图片描述
最开始不是很懂这个,感谢KingZhang:https://blog.csdn.net/weixin_45911397/article/details/119682930

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 7;
#define ll long long
#define x first
#define y second
#define pii pair<int ,int >
const int mod = 1e9 + 7;

ll qpow(ll a, ll b, ll p)
{
    ll ans = 1;
    while (b)
    {
        if(b & 1) ans = ans * a % p;
        b >>= 1;
        a = a * a % p;
    }
    return ans;
}
ll infac[maxn];
ll a[maxn], ans[maxn],res[maxn];
void solve()
{
    infac[1] = 1;
    for(int i = 1; i < maxn; i++)
    {
        infac[i] = qpow(i, mod - 2, mod);
    }
    a[3] = a[4] = 2;
    for(int i= 5;i<maxn;i++) {
        int mid=(i+1)/2;
        a[i]=(a[mid]+a[i-mid+1]-1+mod)%mod;
    }
    ans[1]=1;ans[2]=2;
    for(int i=3;i<maxn;i++){
        ans[i]=(ans[i-1]+a[i])%mod;
    }
    res[1]=1;
    for(int i=2;i<maxn;i++){
        res[i] = (2*infac[i]%mod*ans[i]%mod-1%mod)%mod;
    }
}

int main()
{
    solve();
    int t = 1;
    scanf("%d", &t);
    while(t--)
    {
        ll n;
        scanf("%lld",&n);
        printf("%lld\n",res[n]);
    }
    return 0;
}

1007 Link with Limit

Problem Description
Link has a function f(x), where x and f(x) are both integers in [1,n].

Let fn(x)=f(fn−1(x)) and f1(x)=f(x), he define the power of a number x
as: g(x)=limn→+∞1n∑i=1nfi(x)

He wants to know whether x has the same power for all x∈[1,n].

Input
The input consists of multiple test cases.

The first line contains an integer T (1≤T≤100) – the number of test
cases.

For each test case:

In the first line, there is an integer n (1≤n≤105).

In the second line, there are n integers, the i-th integer shows the
value of f(i) (1≤f(i)≤n).

It is guaranteed that the sum of n over all test cases will not exceed
106.

Output
For each test case, output "YES’’ if it is possible to achieve his goal, or "NO’’ otherwise.

建图,点 向点 连边,那么 迭代的过程实质上是在图上行走的过程。原题实际上问的是每一个环的
点权平均值是否相同,使用任意方法找出所有环并求出平均值即可。
这里使用dfs

#include<cstdio>
#include<iostream>
#include<cstring>
#define ll long long
using namespace std;
double a[100010];
int vis[100010];
double sum[100010];
int cnt = 0,flag = 0;
double ans = 0;
void dfs(int x)
{
	if(vis[x]==0 && flag==0)
	{
		vis[x]=1;
		dfs(a[x]);
	}
	else
	{
		if(vis[x]==2)
		{
			flag = -1;
			cnt--;
			return;
		}
		flag = x;
		ans++;
		sum[cnt]+=a[x];
		vis[x]=2;
		return;
	}
	if(flag>0)
	{
		vis[x]=2;
		if(flag==x)
		{
			sum[cnt]/=ans;
			flag = -1;
			return;
		}
		else
		{
			ans++;
			sum[cnt]+=a[x];
		}
	}
	else
	{
		vis[x]=2;
		return;
	}
}

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		cnt = 0;
		memset(vis,0,sizeof(vis));
		memset(sum,0,sizeof(sum));
		memset(a,0,sizeof(a));
		int n;
		cin>>n;
		for(int i = 1; i <= n; i++)
		{
			scanf("%lf",&a[i]);
		}
		for(int i = 1; i <= n; i++)
		{
			ans = flag = 0;
			if(!vis[i])
			{
				cnt++;
				dfs(i);
			}
		}
		int f = 0;
		for(int i = 2; i <= cnt; i++)
		{
			if(sum[i] != sum[i-1])
			{
				f=1;
				break;
			}
		}
		f?printf("NO\n"):printf("YES\n");
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值