二分查找法
/* 在数组b中查找是否有数组a中的元素 */
#include <stdio.h>
#include <stdlib.h>
int comp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int main()
{
int n, m;
int i, j, x, y, s, mid;
int a[100010], b[100010];
while (scanf("%d%d", &n, &m) != EOF)
{
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
for (i = 0; i < m; i++)
scanf("%d", &b[i]);
qsort(a, n, sizeof(int), comp);
for (i = 0; i < m; i++)
{
x = n - 1;
y = 0;
s = 1;
while (x >= y)
{
mid = (x + y) / 2;
if (b[i] == a[mid])
{
printf("yes\n");
s = 0;
break;
}
else
if (b[i] < a[mid])
x = mid - 1;
else
y = mid + 1;
}
if (s == 1)
printf("no\n");
}
}
return 0;
}
bool three_divide_search(int *a, int n, int val)///数组a,长度n, a[0]-a[n-1],查找val,若存在返回true
{
///数组已从小到大排好序
if (val<a[0] || val>a[n - 1])
return false;
int ll = 0, rr = n - 1;
int mid1, mid2;
while (ll <= rr)
{
int len = rr - ll + 1;
if (len == 1)
return a[ll] == val;
else if (len == 2)
return (a[ll] == val) || (a[rr] == val);
mid1 = len / 3 + ll;
mid2 = len / 3 * 2 + ll;
if (a[mid1] == val)
return true;
else if (a[mid1] > val)
rr = mid1 - 1;
else///在mid1+1,rr中找
{
if (a[mid2] == val)
return true;
else if (a[mid2] > val)
{
ll = mid1 + 1;
rr = mid2 - 1;
}
else ll = mid2 + 1;
}
}
return false;
}
高斯消元
#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
int equ, var; ///有equ个方程,var个变元。增广阵行数为equ, 分别为0到equ - 1,列数为var + 1,分别为0到var.
int a[maxn][maxn];
int x[maxn]; ///解集.
bool free_x[maxn]; ///判断是否是不确定的变元.
int free_num;
void Debug(void)
{
int i, j;
for (i = 0; i < equ; i++)
{
for (j = 0; j < var + 1; j++)
printf("%d ",a[i][j]);
printf("\n");
}
printf("\n");
}
inline int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a%b);
}
inline int lcm(int a, int b)
{
return a / gcd(a, b) * b;
}
///高斯消元法解方程组(-2表示有浮点数解,但无整数解,-1表示无解,表示唯一解,大于0表示无穷解,并返回自由变元的个数)
int Gauss(void)
{
int i, j, k, ta, tb, LCM, temp, free_x_num;
int max_r; ///当前这列绝对值最大的行.
int col; /// 当前处理的列.
int free_index;///转换为阶梯阵.
col = 0; /// 当前处理的列.
for (k = 0; k < equ && col < var; k++, col++)///枚举当前处理的行.
{///找到该col列元素绝对值最大的那行与第k行交换
max_r = k;
for (i = k + 1; i < equ; i++)
{
if (abs(a[i][col]) > abs(a[max_r][col]))
max_r = i;
}
if (max_r != k)///与第k行交换.
{
for (j = k; j < var + 1; j++)
swap(a[k][j], a[max_r][j]);
}
if (a[k][col] == 0)///说明该col列第k行以下全是0了,则处理当前行的下一列.
{
k--;
continue;
}
for (i = k + 1; i < equ; i++)///枚举要删去的行.
{
if (a[i][col] != 0)
{
LCM = lcm(abs(a[i][col]), abs(a[k][col]));
ta = LCM / abs(a[i][col]), tb = LCM / abs(a[k][col]);
if (a[i][col] * a[k][col] < 0) tb = -tb; ///异号的情况是两个数相加.
for (j = col; j < var + 1; j++)
a[i][j] = a[i][j] * ta - a[k][j] * tb;
}
}
}
Debug();
for (i = k; i < equ; i++)///无解的情况
{
if (a[i][col] != 0)
return -1;
}
if (k < var)///无穷解的情况
{
for (i = k - 1; i >= 0; i--)
{
free_x_num = 0;
for (j = 0; j < var; j++)
{
if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
}
if (free_x_num > 1) continue; ///无法求解出确定的变元.
temp = a[i][var];
for (j = 0; j < var; j++)
{
if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];
}
x[free_index] = temp / a[i][free_index]; ///求出该变元.
free_x[free_index] = 0; ///该变元是确定的.
}
return var - k; ///自由变元有var - k个
}
for (i = var - 1; i >= 0; i--)///唯一解的情况
{
temp = a[i][var];
for (j = i + 1; j < var; j++)
{
if (a[i][j] != 0)
temp -= a[i][j] * x[j];
}
if (temp % a[i][i] != 0) return -2; ///说明有浮点数解,但无整数解.
x[i] = temp / a[i][i];
}
return 0;
}
int main(void)
{
int i, j;
while (scanf("%d %d", &equ, &var) != EOF)
{
memset(a, 0, sizeof(a));
memset(x, 0, sizeof(x));
memset(free_x, 1, sizeof(free_x)); ///一开始全是不确定的变元.
for (i = 0; i < equ; i++)
{
for (j = 0; j < var + 1; j++)
{
scanf("%d", &a[i][j]);
}
}
free_num = Gauss();
if (free_num == -1) printf("无解!\n");
else if (free_num == -2) printf("有浮点数解,无整数解!\n");
else if (free_num > 0)
{
printf("无穷多解! 自由变元个数为%d\n", free_num);
for (i = 0; i < var; i++)
{
if (free_x[i]) printf("x%d 是不确定的\n", i + 1);
else printf("x%d: %d\n", i + 1, x[i]);
}
}
else
{
for (i = 0; i < var; i++)
printf("x%d: %d\n", i + 1, x[i]);
}
printf("\n");
}
return 0;
}
多项式求根
double fabs(double x)
{
return (x < 0) ? -x : x;
}
double f(int m, double c[], double x)
{
int i;
double p = c[m];
for (i = m; i > 0; i--)
p = p * x + c[i-1];
return p;
}
int newton(double x0, double *r,double c[], double cp[], int n,
double a, double b, double eps)
{
int MAX_ITERATION = 1000;
int i = 1;
double x1, x2, fp, eps2 = eps/10.0;
x1 = x0;
while (i < MAX_ITERATION)
{
x2 = f(n, c, x1);
fp = f(n-1, cp, x1);
if ((fabs(fp) < 0.000000001) && (fabs(x2) > 1.0))
return 0;
x2 = x1 - x2 / fp;
if(fabs(x1-x2) < eps2)
{
if (x2 < a || x2 > b)
return 0;
*r = x2;
return 1;
}
x1 = x2;
i++;
}
return 0;
}
double Polynomial_Root(double c[], int n, double a, double b, double eps)///多项式系数c[],多项式度数n,求在[a,b]间的根
{
double *cp;
int i;
double root;
cp = (double *)calloc(n, sizeof(double));
for(i = n - 1; i >= 0; i--)
cp[i] = (i+1) * c[i+1];
if (a > b)
{
root = a;
a = b;
b = root;
}
if((!newton(a, &root, c, cp, n, a, b, eps)) &&
(!newton(b, &root, c, cp, n, a, b, eps)))
newton((a+b)*0.5, &root, c, cp, n, a, b, eps);
free(cp);
if (fabs(root) < eps)
return fabs(root);
else
return root;
}