数论
1. 计算1至n中数字X出现的次数
// 计算数字 X 在 1-n 中出现的次数。
int count(int n, int x) {
int cnt = 0, k;
for (int i = 1;k = n / i;i *= 10) {
// 高位的数字。
int high = k / 10;
if (x == 0) {
if (high) {
high--;
} else {
break;
}
}
cnt += high * i;
// 当前位的数字。
int cur = k % 10;
if (cur > x) {
cnt += i;
} else if (cur == x) {
// n - k * i 为低位的数字。
cnt += n - k * i + 1;
}
}
return cnt;
}
2. 匹克定理
通过已知三者的任意两个都可以求第三个未知量
两坐标的x,y差值的公约数可以求两点之间的整数点
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+5;
struct Node
{
ll x;
ll y;
} a[MAXN];
ll n,kk;
ll SS()
{
ll area=0;
for(int i=0; i<n; i++)
{
kk=(i+1)%n;
area+=a[i].x*a[kk].y-a[kk].x*a[i].y;
}
if(area<0) area=-area;
area=area/2;
return area;
}
int main()
{
scanf("%lld",&n);
memset(a,0,sizeof(a));
ll xx,yy;
ll cnt=0;
for(ll i=0; i<n; i++)
{
scanf("%lld%lld",&a[i].x,&a[i].y);
if(i!=0)
{
xx = abs(a[i].x-a[i-1].x);
yy = abs(a[i].y-a[i-1].y);
cnt+=__gcd(xx,yy);
}
}
xx = abs(a[n-1].x-a[0].x);
yy = abs(a[n-1].y-a[0].y);
cnt+=__gcd(xx,yy);
ll area = SS();
ll ans = area - cnt/2 +1;
printf("%lld\n",ans);
}
3. 牛顿迭代法判断是否可以开方
c++(数不大的时候可用)
int mySqrt(int x) {
long resutSqrt = x;
while (resutSqrt * resutSqrt > x) {
resutSqrt = (resutSqrt + x/resutSqrt) / 2; // 此处应该把分母2提到最后项,不然两次除以2后相加会有偏差
}
return (int)resutSqrt;
}
java实现大数
// 判断是否为完全平方数
public static boolean is_square(BigInteger sqrttest){
// 牛顿法求解平方根, 求解a的平方根
// x为a的平方根,x的初始值为1, 按x = (x+a/x)/2迭代, 误差为error
BigDecimal x = BigDecimal.ONE;
BigDecimal a = new BigDecimal(sqrttest.toString());
BigDecimal eps = new BigDecimal("1");
final BigDecimal error = new BigDecimal("1E-10");
int scale = 100;
// 进入循环
while(eps.compareTo(error) == 1){ // eps > error
x = x.add(a.divide(x, scale, BigDecimal.ROUND_HALF_UP)).divide(new BigDecimal("2.0"), scale, BigDecimal.ROUND_HALF_UP);
eps = x.multiply(x).subtract(a).abs();
}
BigInteger sqrt = x.toBigInteger(); // 求平方根的整数部分
if(sqrt.pow(2).compareTo(sqrttest) == 0)
return true;
else
return false;
}