A.小H的小猫
题意
以 x 轴和 y 轴为墙,原点为墙角,小猫在墙角,给出若干个点,求能否能用篱笆绕着点将小猫围在墙角,求篱笆的最短总长
思路
- 1.在纸上简单画图可以证明,必须要有一个点在 x 轴,一个点在 y 轴上才可以围住。
- 2.而离原点最近的两个点可以围成最短的
- 3.套一下两点距离公式
坑点
- 1.画图证明,不够严谨
- 2.精度
- 3.卡了cin和cout的时间复杂度
代码
#include<bits/stdc++.h>
using namespace std;
struct name
{
double x;
double y;
double len;
}num[1000005];
double func (double a,double b,double c,double d)//求两点距离
{
double dis=sqrt((c-a)*(c-a)+(d-b)*(d-b));
return dis;
}
bool cmp(name a,name b)//自定义结构体排序
{
return a.len<b.len;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&num[i].x,&num[i].y);
num[i].len=func(num[i].x,num[i].y,0,0);
}
sort(num,num+n,cmp);
int res1=-1,res2=-1;
for(int i=0;i<n;i++)
{
if(num[i].x==0&&res1==-1)
{
res1=i;
}
if(num[i].y==0&&res2==-1)
{
res2=i;
}
if(res1!=-1&&res2!=-1)
{
break;
}
}
double ans=0;
if(res1!=-1&&res2!=-1)
{
ans+=func(num[res1].x,num[res1].y,num[res2].x,num[res2].y);
printf("%.10lf\n",ans);
}else{
printf("Poor Little H!",ans);
}
return 0;
} 总结
简单题,需快速写出。
小H的数列
题意
给出一个一元二次方程,求解。
思路
- 1.根据样例解释,可以简单的推一下结论
- 2.可知a1=1,s2=4,a3=9,an为n的平方
- 3.数据这么大,肯定是高精度啦
坑点
- 1.套个高精度模板
- 2.暴力过一半
代码
pow骗分,用多了有精度问题,慎有用
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
long long int n;
cin>>n;
cout<<pow(n,2);
return 0;
}高精度 满分 裸模板
#include <iostream>
#include <vector>
using namespace std;
vector<int> mul(vector<int> &A, vector<int> &B) {
vector<int> C(A.size() + B.size(), 0); // 初始化为 0,且999*99最多 5 位
for (int i = 0; i < A.size(); i++)
for (int j = 0; j < B.size(); j++)
C[i + j] += A[i] * B[j];
int t = 0;
for (int i = 0; i < C.size(); i++) { // i = C.size() - 1时 t 一定小于 10
t += C[i];
C[i] = t % 10;
t /= 10;
}
while (C.size() > 1 && C.back() == 0) C.pop_back(); // 必须要去前导 0,因为最高位很可能是 0
return C;
}
int main() {
string a, b;
cin >> a ; // a = "1222323", b = "2323423423"
b=a;
vector<int> A, B;
for (int i = a.size() - 1; i >= 0; i--)
A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i--)
B.push_back(b[i] - '0');
auto C = mul(A, B);
for (int i = C.size() - 1; i >= 0; i--)
cout << C[i];
return 0;
}
总结
裸模板,结论很好猜,套个模板,2分钟就结束了
小H的糖果
题意
给定n,两种操作,操作1:n 除以 k(如果能整除),操作2:减去 1,求使 n 变为 1 的最少操作数。
思路
- 1.题目思路转换到位,就很好做了
- 2.先把n变为能被k整除的数(通过操作2)
- 3.再整除k,模拟即可
坑点
- 1.超时一时爽,一直超时一直爽,卡我endl,我裂开了,我就说为什么"\n"就过,endl就超时,导致比赛时没拿到分(原因:endl比"\n"多一个刷新缓存,影响效率),这件事告诉我们,endl少用...
- 2.从乘法和加法,推到减法和除法,需要一定的思维能力
- 3.学会优化,别减1就真去一个个减1
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--)
{
long long int k,n,ans=0;
cin>>k>>n;
if(k==1)
{
cout<<n-1<<"\n";
continue;
}
while(n>=k)
{
ans+=n%k;//使之n能被k整除,所以需要把n变成能被k整除的数
ans++;//整除则+1
n=n/k;
}
ans+=n-1;//while循环结束的数小于等于k,则需要把其变为1
cout<<ans<<"\n";
}
return 0;
} 总结
除了卡了时间以外,题目还算有趣,类似的在CF见过不少。

京公网安备 11010502036488号