牛客IOI周赛27-普及组

牛客IOI周赛27-普及组

T1.小H的小猫

  • 题目描述

小 H 有一只小猫,这只小猫在原点 (0,0) 的位置。我们将 x 轴和 y 轴的正半轴看作两面墙,原点 (0,0) 的位置看作墙角。现在,在第一象限、x 轴和 y 轴的正半轴上有 n 个木桩,这些木桩看作没有任何大小的点,小 H 可以用篱笆将这些木桩两两相连。

请你求出小 H 能否用篱笆将小猫围在墙角。如果可以,请输出小 H 在保证能够围住小猫的情况下所需要花费的最短篱笆总长,并将答案保留小数点后 10 位,否则输出 “Poor Little H!”。

围在墙角的定义:即这些篱笆与坐标轴构成了一个多边形。

  • 输入描述:

第一行一个数 n。
接下来 n 行,第 i 行表示第 i 个木桩的坐标xi,yi

  • 输出描述:

共一行,一个 10 位小数或者是输出 “Poor Little H!”,若为 10 位小数即为要求的最短篱笆长度。

示例1
输入

3
0.0 1.0
1.0 0.0
1.0 1.0

输出

1.4142135624
  • 说明

在这里插入图片描述

示例2
输入

2
1.0 0.0
0.1 1.0

输出

Poor Little H!

解法

可以从题意得出,只有两个分别在两条坐标轴上的点才能将小猫围住,而且由于第三边小于其他两条边的和可得为更优解,所以我们只需要找出距离远点最近得两个点然后根据勾股定理算出答案就行了,误解的情况就是至少有一条坐标轴上没有点

代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    double hzx=999999999,zzx=999999999;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        double x,y;
        scanf("%lf%lf",&x,&y);
        if(x>0&&y==0)hzx=min(hzx,x);
        if(x==0&&y>0)zzx=min(zzx,y);
    }
    if(hzx==999999999||zzx==999999999)printf("Poor Little H!");
    else printf("%.10lf",sqrt(hzx*hzx+zzx*zzx));
    return 0;
}

T2小H的数列

链接:https://ac.nowcoder.com/acm/contest/11234/B
来源:牛客网

  • 题目描述

小 H 有一个数列,这个数列满足
a1=1,4*a[i-1]*a[i]=(a[i-1]+a[i])^2,a[i-1]<a[i]&&i>=2
且保证每一项都不为 0。现在给你 n,请你求出 a[n]的值。

  • 输入描述:

一行,一个正整数 n。

  • 输出描述:

一行,一个整数表示 a[n]
的值。
示例1
输入

2

输出

4

解法

经过手动算出前几项为1,4,9,16,25可以得出要求的就是n^2,但是数据范围去到了10的10086次方,所以要加上高精度

代码

#include<bits/stdc++.h>
using namespace std;
char s[11000];
int a[11000],b[11000<<1];
int main()
{
    scanf("%s",s);
    int n=strlen(s);
    for(int i=0;i<n;i++)a[i]=s[n-1-i]-'0';
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            b[i+j]+=a[i]*a[j];
    n=(n<<1)-1;
    for(int i=0;i<n;i++)b[i+1]+=b[i]/10,b[i]%=10;
    while(b[n])b[n+1]=b[n]/10,b[n]%=10,++n;
    for(int i=n-1;i>=0;i--)printf("%d",b[i]);
    return 0;
}

T3小H的糖果

  • 题目描述

小 H 生日的那一天,有人送给了小 H 1 颗糖果。小 H 觉得自己的糖果太少了,于是他学会了两种魔法:
使糖果数 +1。
让每一颗糖果分裂成 k 颗糖果,即让糖果总数乘以 k
小 H 想知道,他最少需要使用多少次魔法才能使糖果数刚好等于小 H 的幸运数字 n。

  • 输入描述:

每个测试点包含多组测试数据。
第一行一个正整数 T,表示数据组数。
接下来共 T 行,每行两个正整数 k,n,含义见题目描述。

  • 输出描述:

共 T 行,每行一个非负整数,表示使糖果数量刚好等于 n 的最少魔法使用次数。

示例1
输入

3
2 3
2 9
114514 1919810

输出

2
4
87602

解法

这个没什么好说的,直接上代码吧

代码

#include<cstdio>
using namespace std;
long long k,n;
int T;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        long long ans=0;
        scanf("%lld%lld",&k,&n);
        if(k==1)ans=n+1;
        else
        {
            while(n)
            {
                ans+=n%k+1;
                n/=k;
            }
        }
        printf("%lld\n",ans-2);
    }
    return 0;
}

T4旅游

  • 题目描述

一放假,小 L 就开心规划好自己的假期安排。

她决定去 n 个旅游景点玩。而这些旅游景点之间达成了合作,某两个景点之间会有价格固定的直通大巴(中间不会在其他景点停车)。因此,小 L 决定旅游期间直接乘坐直通大巴在各个旅游景点间往返,并且她希望每次前往另一个景点时花费最小。
由于现在处于疫情期间,每个景点都应该按照规定进行消毒。因为小 L 非常怕感染,所以她决定,只乘坐起点和目的地都进行过至少一次消毒的大巴。

  • 输入描述:

第一行是 n,m,s,q。代表这 n 个景点之间有 m 条线路(即直通大巴),小 L 现在正处在编号为 s 的景点,q 为信息数量。

我们默认 s 号景点已消过毒。

接下来 m 行,每行三个数 u,v,w。代表编号为 u 的景点与编号为 v 的景点之间存在票价为 w 的单向(从 u 到 v)直通大巴。(存在重边和自环,且有可能 u=v)

接下来 q 行是信息,每行两个数 op,x。

共有两种情况:

1 x,代表编号为 x 的景点进行了一次消毒。
2 x,代表小 L 要从当前景点 y 去到编号为 x 的景点。请注意,如果小 L 不能到达 x 号景点那么她的“当前位置”不变,即仍然在 y 号景点。否则“当前位置”为 x 号景点。

  • 输出描述:

对于每个 op=2 的操作,如果 x 号景点没有进行过至少一次消毒,或者小 L 无法到达 x 号景点,请输出 -1 。否则,请输出从当前景点出发到 x 号景点的最小费用。

示例1
输入

4 7 1 4
1 2 6335
3 3 6963
1 2 9962
2 1 2392
4 2 154
2 2 7422
1 3 9896
1 1
1 3
2 1
2 3

输出

0
9896

解法:

差不多等于Floyd裸题

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXM = 8000010;
int n, m, s, q;
int dis[510][510];
int xd[510];
void f(int x)
{
	for (int i = 1;i <= n;i++)
	{
		for (int j = 1;j <= n;j++)
		{
			dis[i][j] = min(dis[i][j], dis[i][x] + dis[x][j]);
		}
	}
}
int main()
{
	memset(dis,0x3f,sizeof(dis));
	int mx=dis[1][1];
	scanf("%d%d%d%d",&n,&m,&s,&q);
	for(int i=1;i<=n;i++) dis[i][i]=0;
	xd[s]=1;
	for(int i=1;i<=m;i++)
	{
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		dis[u][v]=min(dis[u][v],w);
	}
	f(s);
	while(q--)
	{
		int c,x;
		scanf("%d%d",&c,&x);
		if(c==1)
		{
			if(!xd[x])f(x);
			xd[x] = 1;
		}
		else
		{
			if(xd[x]==0||dis[s][x]==mx)
			{
				printf("-1\n");
				continue;
			}
			else
			{
				printf("%d\n", dis[s][x]);
				s=x;
			}
		}
	}
    return 0;
}

完结撒花

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值