学习算法已经有一段时间了,但是也要经常回顾基础,有些题会给自己很精妙的感觉,总结了几道洛谷入门级题单中比较经典的几道。
【入门1】顺序结构
P2181 对角线
这道题非常精妙了,开始我认为是一道画图找规律的题,在做到八边形的时候感觉这个有点儿像斐波那契数列,然后发现一个规律,一个交点与四个顶点有关,由此可知,在n个顶点中任意找出四个点便可以形成一个顶点,由于与顺序无关,所以是组合数
C
n
4
C_n^4
Cn4,所以公式也就是
n
(
n
−
1
)
(
n
−
2
)
(
n
−
3
)
24
\displaystyle { \frac{n(n-1)(n-2)(n-3)}{24}}
24n(n−1)(n−2)(n−3)。
当然,这个题没有那么简单,根据数据范围就知道了
1
0
5
10^5
105的数据,long long
也存不下啊,在这个时候,我们还是不想轻易写高精度的,就需要一些玄学数学方法了,首先,将
24
24
24重新拆回
2
∗
3
∗
4
2*3*4
2∗3∗4,
n
(
n
−
1
)
n(n-1)
n(n−1)是一定会被
2
2
2整除的,
n
(
n
−
1
)
(
n
−
2
)
n(n-1)(n-2)
n(n−1)(n−2)是一定可以被
3
3
3整除的,
n
(
n
−
1
)
(
n
−
2
)
(
n
−
3
)
n(n-1)(n-2)(n-3)
n(n−1)(n−2)(n−3)是一定可以被
4
4
4整除的,所以我们再写代码的时候就是这样的n*(n-1)/2*(n-2)/3*(n-3)/4
就完美避免了超出范围的情况。
最后一个隐藏的知识点unsigned long long
是long long
大小的两倍,对这个有困惑的话自己翻书吧。
代码如下:
#include <bits/stdc++.h>
using namespace std;
unsigned long long n;
int main()
{
scanf("%lld",&n);
printf("%lld\n",n*(n-1)/2*(n-2)/3*(n-3)/4);
return 0;
}
【入门2】分支结构
P5714 【深基3.例7】肥胖问题
这道题也给了我惊喜,由于scanf
printf
在输入输出的时候速度比较快,一直深受我的喜爱,但我没想到的是cout
在输出的时候有默认精度的功能,cout
在浮点型输出时默认精度为六位,是精度哦,不是小数点后保留位数,也就是说,比如234.335467
这个数,cout
在输出时会输出234.335
,printf
默认输出是234.335467
,这在一些情况下给我们节省了很多事情。
代码如下:
#include <bits/stdc++.h>
using namespace std;
double a,b,an;
int main()
{
scanf("%lf %lf",&a,&b);
an=a/(b*b);
if(an<18.5) printf("Underweight\n");
else if(an<24) printf("Normal\n");
else cout<<an<<endl<<"Overweight"<<endl;
return 0;
}
【入门3】循环结构
P1720 月落乌啼算钱
这道题算不上精妙,但是科普作用非常强,众所周知,斐波那契数列是有总结式的,所以本质就是在考斐波那契数列,当然,硬算我也是没意见了,只不过蒟蒻只会递推。
#include <bits/stdc++.h>
using namespace std;
long long n,a=1,b=1,c=1;
int main()
{
scanf("%lld",&n);
for(long long i=3;i<=n;i++)
{
c=a+b;
a=b;
b=c;
}
if(!n) c=0;
printf("%lld.00\n",c);
return 0;
}