1030 完美数列 (25point(s))

本文介绍了一种求解完美数列的最大长度的算法。给定一个正整数数列和参数p,若数列中最大值不超过最小值乘以p,则称其为完美数列。文章提供了两种算法实现,包括基本的双指针方法和优化后的二分查找法,旨在从给定的正整数集合中找出最长的完美数列。

给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。

现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:

输入第一行给出两个正整数 N 和 p,其中 N(≤10​5​​)是输入的正整数的个数,p(≤10​9​​)是给定的参数。第二行给出 N 个正整数,每个数不超过 10​9​​。

输出格式:

在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。

输入样例:

10 8
2 3 20 4 5 1 6 7 8 9

输出样例:

8

 

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

int main()
{
    int n, p;
    cin >> n >> p;
    int a[n];
    for(int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    sort(a, a + n);
    int i = 0, j = 0;
    int ans = 1;
    while(i < n && j < n)
    {
        while(j < n && a[j] <= (long long)a[i] * p) j++;
        ans = max(ans, j - i);
        i++;
    }
    cout << ans;

    return 0;
}

优化:用二分法找j, 在这种方法要考虑序列中所有数都不超过a[i]*p的情况

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100010;
int n, p, a[maxn];
int binarySearch(int i , long long x)
{
    if(a[n - 1] <= x) return n;
    int left = i + 1, right = n - 1;
    while(left < right)
    {
        int mid = (left + right) / 2;
        if(a[mid] <= x)
        {
            left = mid + 1;
        }
        else
        {
            right = mid;
        }
    }
    return left;
}
int main()
{
    cin >> n >> p;
    for(int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    sort(a, a + n);
    int ans = 1, i;
    for(i = 0; i < n; i++)
    {
        int j = binarySearch(i, (long long)a[i] * p);
        ans = max(j - i, ans);
    }
    cout << ans;
    return 0;
}

 

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <limits.h> #define EPS 1e-9 //浮点比较 #define MOD 998244353 //取模运算 #define MAX_LL 1000010//大型数组 #define MAX_L 1010 //小型数组 #define MAX_N 11 //矩阵阶数 #define PI 3.141592653//通用常数 #define EU 2.718281828//通用常数 #define in int #define ll long long #define db double #define ch char #define vd void #define uin unsigned int #define ull unsigned long long #define uch unsigned char #define br break #define cn continue #define rt return #define sc scanf #define pr printf //支持单元输入 #define scin(x) sc("%d", &(x)) #define scll(x) sc("%lld", &(x)) #define scdb(x) sc("%lf", &(x)) //支持空白略去 #define scch(x) sc(" %c", &(x)) #define scst(x) sc(" %s", (x)) //支持二元输入 #define scin2(x,y) sc("%d%d", &(x), &(y)) #define scll2(x,y) sc("%lld%lld", &(x), &(y)) #define scdb2(x,y) sc("%lf%lf", &(x), &(y)) //支持一元输出 #define prin(x) pr("%d", x) #define prll(x) pr("%lld", x) #define prdb(x) pr("%lf", x) #define prch(x) pr("%c", x) #define prst(x) pr("%s", x) //支持一元换行输出 #define prinn(x) pr("%d\n", x) #define prlln(x) pr("%lld\n", x) #define prdbn(x) pr("%lf\n", x) #define prchn(x) pr("%c\n", x) #define prstn(x) pr("%s\n", x) //支持一元精度输出 #define prdbr(x, r) pr("%.*lf", (r), (x)) //支持一元精度换行输出 #define prdbnr(x, r) pr("%.*lf\n", (r), (x)) //支持换行输出 #define prn pr("\n") //支持空格输出 #define prb pr(" ") //支持最判断 #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) //支持浮点相等判断 #define CEPS(a, b) (fabs((a) - (b)) < EPS) //函数主体 //输入输出辅助 //高效输入(大量数据读取) in fast_read() { in x = 0, f = 1; ch c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -f; c = getchar(); } while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } rt x* f; } //辅助一维数组输入([0,n)) vd sc_arr1(in arr[], in n) { for (in i = 0; i < n; i++) { scin(arr[i]); } } //辅助一维数组输出([0,n))(自动去除换行符号) vd pr_arr1(in arr[], in n) { for (in i = 0; i < n; i++) { pr("%d%c ", arr[i], " \n"[i == n - 1]); } } //辅助二维数组输入([0,n))(嵌fast_read) vd sc_arr2(in arr[][MAX_N], in row, in col) { for (in i = 0; i < row; i++) { for (in j = 0; j < col; j++) { arr[i][j] = fast_read(); } } } //辅助二维数组输出([0,n)) vd pr_arr2(in arr[][MAX_N], in row, in col) { for (in i = 0; i < row; i++) { for (in j = 0; j < col; j++) { pr("%d ", arr[i][j]); } pr("\n"); } } //基础数学计算 //计算模加法/减法 ll norm(ll x) {//工具函数(映射到[0,MOD-1];处理负数) rt(x % MOD + MOD) % MOD; } ll mod_add(ll a, ll b) {//模加法 rt norm(a + b); } ll mod_sub(ll a, ll b) {//模减法 rt norm(a - b); } //计算模乘法(快速版) ll mod_qmul(ll a, ll b) { a %= MOD; b %= MOD; ll res = 0; while (b > 0) { if (b & 1) { res = (res + a) % MOD; } a = (a << 1) % MOD; b >>= 1; } rt res; } //计算模乘法(基础版) ll mod_fmul(ll a, ll b) { rt((a % MOD) * (b % MOD)) % MOD; } //计算斐波那契数列第n个数(非递归) ll fibonacci1(in n) { if (n == 0) rt 0; if (n == 1) rt 1; ll prev = 0; ll curr = 1; ll next; for (in i = 2; i <= n; i++) { next = prev + curr; prev = curr; curr = next; } rt curr; } //计算斐波那契数列第n个数(仅递归) ll fibonacci2(in n) { if (n == 0) { rt 0; } else if (n == 1 || n == 2) { rt 1; } rt fibonacci2(n - 1) + fibonacci2(n - 2); } //计算斐波那契数列第n个数(递归;预存储;重复调用;取模;小n;越界MAX_L#-1) ll mem[MAX_L] = { 0 };//存储数组 ll vis[MAX_L] = { 0 };//记忆数组 vd reset() {//初始化记忆数组 memset(vis, 0, sizeof(vis)); } ll fibonacci_mem(in n) {//(嵌mod_add) if (n < 0 || n >= MAX_L) rt -1; if (n == 0) rt 0; if (n == 1) rt 1; if (vis[n]) rt mem[n]; mem[n] = mod_add(fibonacci_mem(n - 1), fibonacci_mem(n - 2)); vis[n] = 1; rt mem[n]; } //计算斐波那契数列第n个数(迭代;非存储;单次调用;取模;大n;越界MAX_L#-1) ll fib_iterative(in n) { if (n < 0 || n >= MAX_L) return -1; if (n == 0) return 0; if (n == 1) return 1; ll f0 = 0, f1 = 1; for (in i = 2; i <= n; ++i) { ll f2 = mod_add(f0, f1); f0 = f1; f1 = f2; } return f1; } //计算给定数n的阶乘(非递归;取模;错误#-1) ll factorial1(in n) { if (n < 0) rt - 1; ll result = 1; for (in i = 2; i <= n; i++) { result = ((result % MOD) * (i % MOD)) % MOD; } rt result; } //计算给定数n的阶乘(仅递归;取模) ll factorial2(in n) { if (n <= 1) { rt 1; } rt((n % MOD) * (factorial2(n - 1) % MOD)) % MOD; } //计算排列数P(对n排k;取模;错误#-1) ll Per(in n, in k) { if (k < 0 || n < 0 || k > n) { rt - 1; } ll result = 1; for (in i = n - k + 1; i <= n; i++) { result = (result * i) % MOD; } rt result; } //计算组合数C(对n组k;特殊;错误#-1) ll Com_sp(in n, in k) { if (k < 0 || n < 0 || k > n) { rt - 1; } if (k > n - k) { k = n - k; } ll result = 1; for (in i = 0; i < k; i++) { result = result * (static_cast<long long>(n) - i) / (static_cast<long long>(i) + 1); } rt result; } //计算幂次(快速幂)(base的exp次方;取模) ll pow_mod(ll base, ll exp) { ll result = 1; while (exp > 0) { if (exp & 1) { result = (result * base) % MOD; } base = (base * base) % MOD; exp >>= 1; } rt result; } //计算二元最大公因数(绝对) ll gcd2(ll a, ll b) { if (a < 0) a = -a; if (b < 0) b = -b; while (b != 0) { ll temp = b; b = a % b; a = temp; } rt a; } //计算三元最大公因数(嵌gcd2) ll gcd3(ll a, ll b, ll c) { rt gcd2(gcd2(a, b), c); } //计算n元最大公因数(数组[1,n);嵌gcd2) ll gcdn(ll arr[], in n) { if (n == 0) rt 0; ll result = arr[0]; for (in i = 1; i < n; ++i) { result = gcd2(result, arr[i]); if (result == 1) br; } rt result; } //计算二元最小公倍数(嵌gcd2) ll lcm2(ll a, ll b) { if (a == 0 || b == 0) rt 0; ll ga = a < 0 ? -a : a; ll gb = b < 0 ? -b : b; ll g = gcd2(ga, gb); rt ga / g * gb; } //计算三元最小公倍数(嵌lcm2) ll lcm3(ll a, ll b, ll c) { rt lcm2(lcm2(a, b), c); } //计算n元最小公倍数(数组[1,n);嵌lcm2) ll lcmn(ll arr[], in n) { if (n == 0) rt 1; ll result = arr[0]; for (in i = 1; i < n; ++i) { result = lcm2(result, arr[i]); if (result == 0) br; } rt result; } //基础数学判断 //判断x是否为回文数(是#1;否#0) in is_palindrome(in x) { if (x < 0) rt 0; in original = x; in reversed = 0; while (x > 0) { reversed = reversed * 10 + x % 10; x /= 10; } rt original == reversed; } //判断x是否为斐波那契数(是#1;否#0) in is_fibonacci(in x) { if (x < 0) rt 0; if (x == 0 || x == 1) rt 1; in a = 0, b = 1; while (b < x) { in next = a + b; a = b; b = next; } rt b == x; } //判断x是否为阶乘数(是#1;否#0) in is_factorial(in x) { if (x <= 0) rt 0; in fact = 1; for (in i = 1; ; ++i) { fact *= i; if (fact == x) rt 1; if (fact > x) rt 0; } } //判断x是否为完全平方数(是#1;否#0) in is_psquare(in x) { if (x < 0) rt 0; in root = (in)sqrt((long double)x) + 0.5; rt root* root == x; } //判断x是否为素数(是#1;否#0) in is_prime(in x) { if (x <= 1) { rt 0; } else if (x <= 3) { rt 1; } else if (x % 2 == 0 || x % 3 == 0) { rt 0; } for (in i = 5; i * i <= x; i += 6) { if (x % i == 0 || x % (i + 2) == 0) { rt 0; } } rt 1; } //判断x是否为2的自然数幂次(是#1;否#0) in is_power2(in x) { rt x > 0 && (x & (x - 1)) == 0; } //任意进制转换 //10进制转2进制(正数;数字转数字版) ll to_bin(ll n) { if (n == 0) rt 0LL; ll bin = 0; ll base = 1; while (n > 0) { bin += (n % 2) * base; n /= 2; base *= 10; } rt bin; } //10进制转2进制(正数;数字转数组版;存入arr;低位在前;#二进制位数>0) in to_bin_arrl(ll n, in arr[]) { if (n == 0) { arr[0] = 0; rt 1; } in i = 0; while (n > 0) { arr[i++] = n % 2; n /= 2; } rt i; } //10进制转2进制(正数;数字转数组版;存入arr;高位在前;#二进制位数>0) in to_bin_arrh(ll n, in arr[]) { if (n == 0) { arr[0] = 0; rt 1; } in temp[64]; in len = 0; while (n > 0) { temp[len++] = n % 2; n /= 2; } for (in i = 0; i < len; ++i) { arr[i] = temp[len - 1 - i]; } rt len; } //10进制转2进制(正数;数组转数组版;len位dec;存入bin;低位在前;#二进制位数>0) in to_bin_2arrl(in dec[], in bin[], in len) { in work[MAX_L]; in temp[MAX_L]; in bin_len = 0; for (in i = 0; i < len; ++i) { work[i] = dec[i]; } while (1) { in all_zero = 1; for (in i = 0; i < len; ++i) { if (work[i] != 0) { all_zero = 0; br; } } if (all_zero) rt bin_len; in carry = 0; for (in i = 0; i < len; ++i) { carry = carry * 10 + work[i]; temp[i] = carry / 2; carry %= 2; } bin[bin_len++] = carry; for (in i = 0; i < len; ++i) { work[i] = temp[i]; } } } //10进制转2进制(正数;数组转数组版;len位dec;存入bin;高位在前;#二进制位数>0) in to_bin_2arrh(in dec[], in bin[], in len) { in work[MAX_L]; in temp[MAX_L]; in bits[MAX_L]; in bit_len = 0; for (in i = 0; i < len; ++i) { work[i] = dec[i]; } while (1) { in all_zero = 1; for (in i = 0; i < len; ++i) { if (work[i] != 0) { all_zero = 0; br; } } if (all_zero) br; in carry = 0; for (in i = 0; i < len; ++i) { carry = carry * 10 + work[i]; temp[i] = carry / 2; carry %= 2; } bits[bit_len++] = carry; for (in i = 0; i < len; ++i) { work[i] = temp[i]; } } if (bit_len == 0) { bin[0] = 0; rt 1; } for (in i = 0; i < bit_len; ++i) { bin[i] = bits[bit_len - 1 - i]; } rt bit_len; } //10进制转2进制(正数;数串转数组版;串num_str;存入bin;低位在前;#二进制位数>0) in str_to_dgt1(const char* str, in digits[]) {//Tool.字符串转数组(#有效长度) in len = 0; while (str[len] != '\0') { if (str[len] >= '0' && str[len] <= '9') digits[len] = str[len] - '0'; else br; ++len; } rt len; } in to_bin_strl(const char* num_str, in bin[]) {//Main.数串转数组(#二进制位数)(嵌str_to_dgt1,to_bin_2arrl) if (num_str == NULL || *num_str == '\0') { bin[0] = 0; rt 1; } in digits[MAX_L]; in d_len = str_to_dgt1(num_str, digits); in all_zero = 1; for (in i = 0; i < d_len; ++i) { if (digits[i] != 0) { all_zero = 0; br; } } if (all_zero) { bin[0] = 0; rt 1; } rt to_bin_2arrl(digits, bin, d_len); } //10进制转2进制(正数;数串转数组版;串num_str;存入bin;高位在前;#二进制位数>0) in str_to_dgt2(const char* str, in digits[]) {//Tool.字符串转数组(#有效长度) in len = 0; while (str[len] != '\0') { if (str[len] >= '0' && str[len] <= '9') digits[len] = str[len] - '0'; else br; ++len; } rt len; } in to_bin_strh(const char* num_str, in bin[]) {//Main.数串转数组(#二进制位数)(嵌str_to_dgt2,to_bin_2arrh) if (num_str == NULL || *num_str == '\0') { bin[0] = 0; rt 1; } in digits[MAX_L]; in d_len = str_to_dgt2(num_str, digits); in all_zero = 1; for (in i = 0; i < d_len; ++i) { if (digits[i] != 0) { all_zero = 0; br; } } if (all_zero) { bin[0] = 0; rt 1; } rt to_bin_2arrh(digits, bin, d_len); } //任意进制转换(2~36间;正数;字符串n转字符组m;错误#-1;正确#0(可忽略rt)) in char_to_value(ch c) {//Tool.字符转数字 if (isdigit(c)) rt c - '0'; if (isupper(c)) rt c - 'A' + 10; if (islower(c)) rt c - 'a' + 10; rt - 1; } ch value_to_char(in val) {//Tool.数字转字符 if (val < 10) rt '0' + val; rt 'A' + val - 10; } in convert_base(const ch* n, in a, in b, ch m[]) {//Main.任意进制转换(嵌char_to_value,value_to_char) if (!n || !m || a < 2 || a > 36 || b < 2 || b > 36) { if (m) m[0] = '\0'; rt - 1; } in len = strlen(n); if (len == 0) { m[0] = '0'; m[1] = '\0'; rt 0; } ll decimal = 0; for (in i = 0; i < len; ++i) { in val = char_to_value(n[i]); if (val == -1 || val >= a) { m[0] = '\0'; rt - 1; } if (decimal > (LLONG_MAX - val) / a) { m[0] = '\0'; rt - 1; } decimal = decimal * a + val; } if (decimal == 0) { m[0] = '0'; m[1] = '\0'; rt 0; } ch temp[65]; in idx = 0; while (decimal > 0) { in r = decimal % b; temp[idx++] = value_to_char(r); decimal /= b; } temp[idx] = '\0'; for (in i = 0; i < idx; ++i) { m[i] = temp[idx - 1 - i]; } m[idx] = '\0'; rt 0; } //字符串综合 //判断字符串str是否为回文序列(是#1) in is_palindrome(const ch* str) { if (str == NULL) { rt 0; } in left = 0; in right = strlen(str) - 1; while (left < right) { if (str[left] != str[right]) { rt 0; } left++; right--; } rt 1; } //要求反转字符串str(整体;破坏性) vd rev_str_all(ch* str) { if (str == NULL) { rt; } in left = 0; in right = strlen(str) - 1; ch temp; while (left < right) { temp = str[left]; str[left] = str[right]; str[right] = temp; left++; right--; } } //要求反转字符串str(字串start到end;破坏性) vd rev_str_range(ch* str, in start, in end) { if (str == NULL || start < 0 || end < 0 || start >= end) rt; while (start < end) { ch temp = str[start]; str[start] = str[end]; str[end] = temp; start++; end--; } } //要求字符串str前端删去n字符(str[0~n-1];破坏性) vd det_frt_n(ch str[], in n) { if (str == NULL) rt; in len = strlen(str); if (n <= 0) rt; if (n >= len) { str[0] = '\0'; rt; } for (in i = n; i <= len; ++i) { str[i - n] = str[i]; } } //要求字符串str末端删去n字符(str[len-n~len-1];破坏性) vd det_end_n(ch str[], in n) { if (str == NULL) rt; in len = strlen(str); if (n <= 0) rt; if (n >= len) { str[0] = '\0'; rt; } str[len - n] = '\0'; } //要求字符串str删去m~n之间字符(str[m~n];破坏性) vd det_range(ch str[], in m, in n) { if (str == NULL) rt; in len = strlen(str); if (m < 1 || n < m) rt; if (n > len) n = len; in start_idx = m - 1; in end_idx = n - 1; if (start_idx >= len) rt; in del_len = end_idx - start_idx + 1; for (in i = end_idx + 1; i <= len; ++i) { str[i - del_len] = str[i]; } } //数组综合 //求数组元素(arr;[0,n-1];取模;嵌mod_add) ll sum_arr_mod(const in arr[], in n) { ll s = 0; for (in i = 0; i < n; i++) { s = mod_add(s, arr[i]); } rt s; } //求数组元素积(arr;[0,n-1];取模;嵌mod_qmul) ll prod_arr_mod(const in arr[], in n) { ll p = 1; for (in i = 0; i < n; i++) { p = mod_qmul(p, arr[i]); } rt p; } //反转数组(arr;[0,n-1];破坏性) vd reverse_arr(in arr[], in n) { for (in i = 0; i < n / 2; i++) { in t = arr[i]; arr[i] = arr[n - 1 - i]; arr[n - 1 - i] = t; } } //对排序数组去重(src[0,srcSize-1]存入dest[0,*destSize-1]) vd remove_same(const ll src[], in srcSize, ll dest[], in* destSize) { if (srcSize == 0) { *destSize = 0; rt; } dest[0] = src[0]; in count = 1; for (in i = 1; i < srcSize; ++i) { if (src[i] != src[i - 1]) { dest[count++] = src[i]; } } *destSize = count; } //求数组的逆序数(arr;[0,n-1];破坏性) in temp_arr[MAX_L];//临时数组 vd merge_sort_inv(in arr[], in left, in right, in* inv_count) {//内层函数(排序)(对arr[left,right]求逆序) if (left >= right) rt; in mid = (left + right) / 2; merge_sort_inv(arr, left, mid, inv_count); merge_sort_inv(arr, mid + 1, right, inv_count); in i = left, j = mid + 1, k = left; while (i <= mid && j <= right) { if (arr[i] <= arr[j]) { temp_arr[k++] = arr[i++]; } else { temp_arr[k++] = arr[j++]; *inv_count += (mid - i + 1); } } while (i <= mid) temp_arr[k++] = arr[i++]; while (j <= right) temp_arr[k++] = arr[j++]; for (i = left; i <= right; i++) arr[i] = temp_arr[i]; } in count_inversions(in arr[], in n) {//外层函数(对arr[0,n-1]求逆序) in inv_count = 0; merge_sort_inv(arr, 0, n - 1, &inv_count); rt inv_count; } //求数组的逆序数(arr;[0,n-1];非破坏性) in temp_arr[MAX_L];//临时数组 in copy_arr[MAX_L];//副本数组 vd merge_sort_inv_nd(in arr[], in left, in right, in* inv_count) {//内层函数(排序)(对arr[left,right]求逆序) if (left >= right) rt; in mid = (left + right) / 2; merge_sort_inv_nd(arr, left, mid, inv_count); merge_sort_inv_nd(arr, mid + 1, right, inv_count); in i = left, j = mid + 1, k = left; while (i <= mid && j <= right) { if (arr[i] <= arr[j]) { temp_arr[k++] = arr[i++]; } else { temp_arr[k++] = arr[j++]; *inv_count += (mid - i + 1); } } while (i <= mid) temp_arr[k++] = arr[i++]; while (j <= right) temp_arr[k++] = arr[j++]; for (i = left; i <= right; i++) arr[i] = temp_arr[i]; } in count_inversions_nd(const in arr[], in n) {//外层函数(对arr[0,n-1]求逆序;非破坏性) for (in i = 0; i < n; ++i) copy_arr[i] = arr[i]; in inv_count = 0; merge_sort_inv_nd(copy_arr, 0, n - 1, &inv_count); rt inv_count; } //求矩阵相乘(A(m*r)*B(r*n)=C(m*n))[0,m) vd mat_mul(in A[][MAX_N], in B[][MAX_N], in C[][MAX_N], in m, in r, in n) { for (in i = 0; i < m; i++) { for (in j = 0; j < n; j++) { C[i][j] = 0; } } for (in i = 0; i < m; i++) { for (in k = 0; k < r; k++) { for (in j = 0; j < n; j++) { C[i][j] += A[i][k] * B[k][j]; } } } } //求矩阵的余子式Mij(n阶,i=row,j=col除余子式)[0,m) vd det_Mij(in A[][MAX_N], in Mij[][MAX_N], in row, in col, in n) { in i = 0, j = 0; for (in r = 0; r < n; r++) { for (in c = 0; c < n; c++) { if (r != row && c != col) { Mij[i][j++] = A[r][c]; if (j == n - 1) { j = 0; i++; } } } } } //求矩阵的行列式det(n阶;嵌det_Mij))[0,m) ll mat_det(in A[][MAX_N], in n) { in det = 0; if (n == 1) { rt A[0][0]; } if (n == 2) { rt A[0][0] * A[1][1] - A[0][1] * A[1][0]; } in temp[MAX_N][MAX_N]; in sign = 1; for (in f = 0; f < n; f++) { det_Mij(A, temp, 0, f, n); det += sign * A[0][f] * mat_det(temp, n - 1); sign *= -1; } rt det; } //求矩阵的转置(m行n列的A转置为T)[0,m) vd mat_tran(in A[][MAX_N], in T[][MAX_N], in m, in n) { for (in i = 0; i < m; i++) { for (in j = 0; j < n; j++) { T[j][i] = A[i][j]; } } } //求矩阵的秩(m行n列的A求rank;非破坏性)[0,m) in mat_rank(ll A[][MAX_N], in m, in n) { ll work[MAX_N][MAX_N]; for (in i = 0; i < m; ++i) { for (in j = 0; j < n; ++j) { work[i][j] = A[i][j]; } } in rank = 0; for (in col = 0; col < n && rank < m; ++col) { in pivot_row = -1; for (in i = rank; i < m; ++i) { if (work[i][col] != 0) { pivot_row = i; br; } } if (pivot_row == -1) cn; if (pivot_row != rank) { for (in j = 0; j < n; ++j) { ll temp = work[rank][j]; work[rank][j] = work[pivot_row][j]; work[pivot_row][j] = temp; } } for (in r = rank + 1; r < m; ++r) { while (work[r][col] != 0) { ll abs_cur = llabs(work[r][col]); ll abs_piv = llabs(work[rank][col]); if (abs_cur >= abs_piv) { ll t = work[r][col] / work[rank][col]; if (t == 0) t = (work[r][col] > 0) ? 1 : -1; for (in j = col; j < n; ++j) { work[r][j] -= t * work[rank][j]; } } else { for (in j = col; j < n; ++j) { ll temp = work[r][j]; work[r][j] = work[rank][j]; work[rank][j] = temp; } } } } rank++; } rt rank; } //排序查找 //泛用交换函数 vd swap(in* a, in* b) { in temp = *a; *a = *b; *b = temp; } //泛用比较函数组(cmp) typedef in(*cmp_fn)(const vd*, const vd*); in incmp_up(const vd* a, const vd* b) {//int升序 in x = *(const in*)a; in y = *(const in*)b; if (x < y) rt - 1; if (x > y) rt 1; rt 0; } in incmp_dn(const vd* a, const vd* b) {//int降序(嵌incmp_up) rt - incmp_up(a, b); } in chcmp_as(const vd* a, const vd* b) {//char字典序 uch x = *(const uch*)a; uch y = *(const uch*)b; rt(x > y) - (x < y); } //冒泡排序(升序;单元;嵌swap)[0,n) vd bubble_sort(in* arr, size_t n) { if (arr == NULL || n < 2) { rt; } for (size_t i = 0; i < n - 1; i++) { in swapped = 0; for (size_t j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { swap(&arr[j], &arr[j + 1]); swapped = 1; } } if (!swapped) { break; } } } //快速排序(基础版本;非cmp升序;单元;嵌swap)[l,r] vd quick_sort(in arr[], in l, in r) { if (l >= r) { rt; } in i = l, j = r; in pivot = arr[(l + r) / 2]; while (i <= j) { while (arr[i] < pivot) i++; while (arr[j] > pivot) j--; if (i <= j) { swap(&arr[i], &arr[j]); i++; j--; } } quick_sort(arr, l, j); quick_sort(arr, i, r); } //快速排序(优化重复;非cmp升序;单元;嵌swap)[l,r] vd quick_sort_3w(in arr[], in l, in r) { if (l >= r) rt; in pivot = arr[l]; in lt = l; in gt = r; in i = l; while (i <= gt) { if (arr[i] < pivot) swap(&arr[i++], &arr[lt++]); else if (arr[i] > pivot) swap(&arr[i], &arr[gt--]); else i++; } quick_sort_3w(arr, l, lt - 1); quick_sort_3w(arr, gt + 1, r); } //快速排序(基础版本;cmp升序版;单元;嵌swap;嵌自定义cmp)[l,r] vd quick_csort(in arr[], in l, in r, cmp_fn cmp) {//调用时:quick_csort(arr,l,r,incmp_up) if (l >= r) { rt; } in i = l, j = r; in pivot = arr[(l + r) / 2]; while (i <= j) { while (cmp(&arr[i], &pivot) < 0) i++; while (cmp(&arr[j], &pivot) > 0) j--; if (i <= j) { swap(&arr[i], &arr[j]); i++; j--; } } quick_csort(arr, l, j, cmp); quick_csort(arr, i, r, cmp); } //快速排序(优化重复;cmp升序版;单元;嵌swap;嵌自定义cmp)[l,r] vd quick_csort_3w(in arr[], in l, in r, cmp_fn cmp) {//调用时:quick_csort_3w(arr,l,r,incmp_up) if (l >= r) rt; in pivot = arr[l]; in lt = l; in gt = r; in i = l; while (i <= gt) { in res = cmp(&arr[i], &pivot); if (res < 0) swap(&arr[i++], &arr[lt++]); else if (res > 0) swap(&arr[i], &arr[gt--]); else i++; } quick_csort_3w(arr, l, lt - 1, cmp); quick_csort_3w(arr, gt + 1, r, cmp); } //二分查找(预升序;找x;成功#arr下标;失败#-1)[0,n) in bin_search(in arr[], in n, in x) { in left = 0, right = n - 1; while (left <= right) { in mid = left + (right - left) / 2; if (arr[mid] == x) rt mid; else if (arr[mid] < x) left = mid + 1; else right = mid - 1; } rt -1; } //二分求解(对预设函数求单零点;常规;成功#解;失败#NAN)[low,high] db test_func1(db x) {//函数示例:x*x-2=0 return x * x - 2; } db bin_solve(db low, db high, db(*f)(db)) {//调用示例:bin_solve(low,high,test_func1) db fl = f(low), fh = f(high); if (fl * fh > 0) return NAN; while (high - low > EPS) { db mid = (low + high) / 2; db fm = f(mid); if (fm == 0) rt mid; if (fm * fl > 0) { low = mid; fl = fm; } else { high = mid; } } return (low + high) / 2; } //二分求解(对预设函数求单零点;递归;成功#解;失败#NAN)[low,high] db test_func2(db x) {//函数示例:x*x-2=0 return x * x - 2; } db bin_solve_s(db low, db high) { db fl = test_func2(low), fh = test_func2(high); if (fl * fh > 0) { return NAN; } db mid = (low + high) / 2; db fm = test_func2(mid); if (high - low < EPS) { return mid; } if (fm * fl > 0) { return bin_solve_s(mid, high); } else { return bin_solve_s(low, mid); } } //几何综合 //判断三点是否共线(xi,yi)(否#0) in is_line(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3) { ll cross = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1); rt cross == 0; } //判断点是否在线段上((x,y)在(x1,y1)(x2,y2)上;否#0)(嵌is_line) in is_pline(ll x, ll y, ll x1, ll y1, ll x2, ll y2) { if (!is_line(x, y, x1, y1, x2, y2)) rt 0; rt(x >= MIN(x1, x2) && x <= MAX(x1, x2) && y >= MIN(y1, y2) && y <= MAX(y1, y2)); } //判断两线段是否相交((x1,y1)(x2,y2)与(x3,y3)(x4,y4);否#0) ll cross_point(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3) {//内层函数 rt(x2 - x1)* (y3 - y1) - (x3 - x1) * (y2 - y1); } in is_cline(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3, ll x4, ll y4) {//外层函数(嵌corss_point) if (MAX(x1, x2) < MIN(x3, x4) || MAX(x3, x4) < MIN(x1, x2) || MAX(y1, y2) < MIN(y3, y4) || MAX(y3, y4) < MIN(y1, y2)) rt 0; ll c1 = cross_point(x1, y1, x2, y2, x3, y3); ll c2 = cross_point(x1, y1, x2, y2, x4, y4); ll c3 = cross_point(x3, y3, x4, y4, x1, y1); ll c4 = cross_point(x3, y3, x4, y4, x2, y2); rt(c1 * c2 <= 0) && (c3 * c4 <= 0); } //计算平面上两点的距离(x1,y1)(x2,y2) db dis_d2(db x1, db y1, db x2, db y2) { db dx = x2 - x1; db dy = y2 - y1; rt sqrt(dx * dx + dy * dy); } //计算立体上两点的距离(xi,yi) db dis_d3(db x1, db y1, db z1, db x2, db y2, db z2) { db dx = x2 - x1; db dy = y2 - y1; db dz = z2 - z1; rt sqrt(dx * dx + dy * dy + dz * dz); } //计算三角形面积(整坐标二倍防浮点)(xi,yi) ll tri_2s(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3) { ll area_2 = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1); rt area_2 < 0 ? -area_2 : area_2; } //计算凸多边形面积(整坐标二倍防浮点)(x[i],y[i],[0,n-1]) ll ply_2s(in n, ll x[], ll y[]) { ll area_2 = 0; for (in i = 0; i < n; ++i) { in j = (i + 1) % n; area_2 += x[i] * y[j] - x[j] * y[i]; } rt llabs(area_2); } //计算三角形周长(xi,yi);嵌dis_d2) db tri_c(db x1, db y1, db x2, db y2, db x3, db y3) { db ab = dis_d2(x1, y1, x2, y2); db bc = dis_d2(x2, y2, x3, y3); db ca = dis_d2(x3, y3, x1, y1); rt ab + bc + ca; } //计算多边形周长(x[i],y[i],[0,n-1];嵌dis_d2) db ply_c(in n, db x[], db y[]) { db p = 0; for (in i = 0; i < n; ++i) { in j = (i + 1) % n; p += dis_d2(x[i], y[i], x[j], y[j]); } rt p; } //时间日期 //判断某年是否为闰年 in is_leap(in year) { rt(year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0); } //求某年某月的天数(switch;嵌is_leap) in d_of_m_sw(in year, in month) { in days = 0; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31; break; case 4: case 6: case 9: case 11: days = 30; break; case 2: days = is_leap(year) ? 29 : 28; break; } rt days; } //求某年某月的天数(array;嵌is_leap) in d_of_m_ar(in year, in month) { if (month < 1 || month > 12) rt - 1; const in days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; in d = days[month]; if (month == 2 && is_leap(year)) d++; rt d; } //求某日期是该年第几天(嵌d_of_m_ar) in d_of_y(in year, in month, in day) { in total = 0; for (in i = 1; i < month; ++i) { total += d_of_m_ar(year, i); } rt total + day; } //求某日期对应的星期数(周日#0) in week(in year, in month, in day) { if (month < 3) { year--; month += 12; } in century = year / 100; year %= 100; in w = (year + year / 4 + century / 4 - 2 * century + (26 * (month + 1)) / 10 + day) % 7; if (w < 0) w += 7; rt(w + 6) % 7; }审核下
最新发布
12-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值