1、贪心思想-市场月饼销量的贪心
#include <cstdio>
#include <iostream>
#include <algorithm>
struct Bing
{
int a; // 库存量
int b; // 总售价
};
// 自定义排序规则
bool cmp(Bing a, Bing b)
{
return ((double)a.b / (double)a.a) > ((double)b.b / (double)b.a);
}
int main()
{
int kinds, total; // 月饼的种类数目 市场最大需求量
scanf("%d%d", &kinds, &total);
Bing arr[kinds]; // 月饼的信息(库存 + 总售价)
int i; // 循环因子
for (i = 0; i < kinds; ++i)
scanf("%d", &(arr[i].a)); // 库存
for (i = 0; i < kinds; ++i)
scanf("%d", &arr[i].b); // 售价
// 单价从高到低排序
std::sort(arr, arr + kinds, cmp);
// 在市场需求量范围内计算总价
int index = 0; // 已售出的总量
double totalsum = 0.0; // 已售出的总价
// 从单价高的先消耗
i = 0;
while (index < total)
{
if (arr[i].a <= total - index)
{
//全部消耗
index += arr[i].a;
totalsum += arr[i].b;
i++;
}
else
{
totalsum += (total - index) * ((double)arr[i].b / (double)arr[i].a);
break;
}
}
printf("%.2f\n", totalsum);
return 0;
}
1、贪心思想-最小数贪心
#include <cstdio>
#include <algorithm>
#include <string.h>
int main()
{
int arr[10];
int i, index = 0;
for (i = 0; i < 10; ++i)
scanf("%d", &arr[i]);
for (i = 0; i < 10; ++i)
{
if (arr[i] != 0)
index += arr[i];
}
int num[index];
memset(num, -1, sizeof(num));
// 存入数组num
//遍历初始值
int loc = 0;
for (i = 0; i < 10; ++i)
{
if (arr[i] != 0)
{
//在num数组连续存入i个i
for (int j = loc; j < loc + arr[i]; ++j)
{
num[j] = i;
}
//更新num数组下标
loc += arr[i];
}
}
//对num数组排序
std::sort(num, num + index);
//交换//贪心越小的数越靠前
//把最前面的0往后移动, 记录0的个数
i = 0, loc = 0;
while (num[i] == 0)
loc++, i++;
//交换
for (i = 0; i < loc; ++i)
{
num[i] = num[i + loc];
num[i + loc] = 0;
}
for (i = 0; i < index; ++i)
printf("%d", num[i]);
printf("\n");
return 0;
}
1、贪心思想-区间贪心
#include <cstdio>
#include <algorithm>
//区间
struct Inteval
{
int x, y;//左右端点
};
//自定义排序规则
bool cmp(Inteval a, Inteval b)
{
if (a.x != b.x)
return a.x > b.x;//左端点从大到小排
else
return a.y < b.y;//右端点从小到大排
}
int main()
{
//从给定的n个区间中选择
//1、输入n个区间
int n, i;
scanf("%d", &n);
Inteval arr[n];
//2、输入n个区间
for (i = 0; i < n; ++i)
scanf("%d%d", &arr[i].x, &arr[i].y);
//3、对n个区间进行排序对左端点从大到小排(方便后续贪心, 每次都挑左端点最大的)
std::sort(arr, arr + n, cmp);
//4、开始选择区间 贪心每次选择最大的(每轮的第1个)并判断
printf("(%d, %d)\n", arr[0].x, arr[0].y);
Inteval loc = arr[0];
for (i = 1; i < n; ++i)
{
if (arr[i].x < loc.x && arr[i].y <= loc.x)
{
printf("(%d, %d)\n", arr[i].x, arr[i].y);
loc = arr[i];
}
else
continue;
}
return 0;
}
2、二分思想 查找=
#include <cstdio>
int BinarySearch(int arr[], int left, int right, int val)
{
int middle;
while (left <= right)
{
middle = (left + right) / 2;
if (arr[middle] == val)
return middle;
else if (arr[middle] < val)
left = middle + 1;
else
right = middle - 1;
}
return -1;
}
int main()
{
const int n = 10;
int A[n] = {1, 3, 4, 6, 7, 8, 10, 11, 12, 15};
printf("%d %d\n", BinarySearch(A, 0, n - 1, 6), BinarySearch(A, 0, n - 1, 9));
return 0;
}
2、二分思想 查找第一个_=
#include <cstdio>
int BinarySearch_1(int arr[], int left, int right, int val)
{
//1、先找大于等于的
int middle, loc;
while (left <= right)
{
middle = (left + right) / 2;
if (arr[middle] < val)
{
//去右半区间找
left = middle + 1;
}
else
{
//2、遍历0~middle-1号位置
if (arr[middle - 1] < val)
return middle;//找到了第一个
else
{
//0~middle-1存在>=val的元素
//(递归调用)二分查找>=val的第一个元素位置
return BinarySearch_1(arr, 0, middle - 1, val);
}
}
}
return -1;//没找到的情况
}
int main()
{
int arr[10] = {1, 2, 2, 3, 4, 5, 7, 7, 8, 8};
for (int i = 0; i < 10; ++i)
printf("%d ", arr[i]);
printf("\n%d %d\n", BinarySearch_1(arr, 0, 9, 3), BinarySearch_1(arr, 0, 9, 7));
return 0;
}
2、二分思想 计算根号2
#include <cstdio>
#include <math.h>
double Binary_Caculate()
{
double left = 1.0, right = 2.0, middle;
middle = (left + right) / 2.0;
while (fabs(pow(middle, 2.0) - 2.0) > 0.00001)
{
if (pow(middle, 2.0) - 2.0 < 0)
{
left = middle + 0.00001;
}
else
{
right = middle - 0.00001;
}
middle = ((double)left + (double)right) / 2;
}
return middle;
}
int main()
{
printf("%.6f\n", Binary_Caculate());
return 0;
}
2、二分思想 求解储水
#include <cstdio>
#include <math.h>
#define pi acos(-1)
double Caculate_h(double R, double r)
{
double left = 0.0, right = R, h = (left + right) / 2.0;
double SR = 0.5 * pi * R * R;
double Sh = R * R * acos((R - h) / R) - (R - h) * pow((2 * R * h - h * h), 0.5);
while (fabs(Sh / SR - r) > 0.00001)
{
if (Sh / SR > r)
right = h - 0.00001;
else
left = h + 0.00001;
h = (left + right) / 2.0;
Sh = R * R * acos((R - h) / R) - (R - h) * pow((2 * R * h - h * h), 0.5);
}
printf("Sh = %.5f, SR = %.5f, 实际r = %lf\n", Sh, SR, Sh / SR);
return h;
}
int main()
{
double R, r;
scanf("%lf", &R);
scanf("%lf", &r);
printf("%.5f, %.5f\n", R, r);
printf("%.5f\n", Caculate_h(R, r));
return 0;
}
2、二分思想 切割木棒
#include <cstdio>
#include <math.h>
#include <algorithm>
double Caculate(double arr[], int len, double left, double right, int k)
{
double middle = (left + right) / 2.0;
int i, index = 0;
for (i = 0; i < len; ++i)
index += (int)(arr[i] / middle);
while (index < k)
{
right = middle - 0.00001;
middle = (left + right) / 2.0;
index = 0;
for (i = 0; i < len; ++i)
index += (int)(arr[i] / middle);
}
//寻找最长木棍
for (double j = middle + 0.00001; j <= arr[0]; j = j + 0.00001)
{
index = 0;
for (i = 0; i < len; ++i)
index += (int)(arr[i] / j);
if (index < k)
return j - 0.00001;
}
return arr[0];
}
int main()
{
int N, K, i;
double arr[N];
scanf("%d%d", &N, &K);
for (i = 0; i < N; ++i)
scanf("%lf", &arr[i]);
// 开始切割
std::sort(arr, arr + N);
double left = 0.0, right = arr[0];
printf("%lf\n", Caculate(arr, N, left, right, K));
return 0;
}
2、二分思想 快速幂
#include <cstdio>
#include <math.h>
typedef long long LL;
LL pow(LL a, LL b, LL m)
{
LL ans = 1;
for (int i = 0; i < b; ++i)
{
ans = ans * a % m;
printf("%lld\n", ans);
}
return ans;
}
int main()
{
LL a = 2, b = 10, m = (LL)pow(10.0, 8.0);
pow(a, b, m);
return 0;
}
3、双指针
#include <cstdio>
void TwoPointers(int arr[], int len, int M)
{
// int i, j, index = 0;
// for (i = 0; i < len; i++)
// for (j = i + 1; j < len; j++)
// {
// index++;
// if (arr[i] + arr[j] == M)
// printf("(%d, %d)\n", arr[i], arr[j]);
// else if (arr[i] + arr[j] > M)
// break;//break 跳出当前的1重循环
// else
// continue;
// }
int i = 0, j = len - 1, index = 0;
while (i < j)
{
if (arr[i] + arr[j] == M)
{
printf("(%d, %d)\n", arr[i], arr[j]);
i++, j--;
}
else if (arr[i] + arr[j] > M)
j--;
else
i++;
index++;
}
printf("共运行%d次\n", index);
}
int main()
{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TwoPointers(arr, sizeof(arr) / sizeof(arr[0]), 8);
return 0;
}