枚举算法(c++版本)
·
一、算法原理和分类
1、枚举算法分为 暴力枚举(双for)、二进制枚举、递归枚举。
2、枚举就是将题目中所有的情况都列出来,然后找到符合条件的那个答案。
二、题目详解
1、暴力枚举试题(https://www.luogu.com.cn/problem/P1003)
(1)首先我们可以创建a, b, g, k四个数组将x轴坐标、y轴坐标、x轴方向长度、y轴方向长度存储起来。
(2)通过从后向前遍历的方式找到覆盖在(x, y)这个坐标点的最上面的地毯。
(3) 对于如何确定给出的点在不在地毯上,我们可以根据 a<= x<=(a+g) 、b<=y<=(b+k)这两个不等式求得。
(4)具体代码如下:
#include <iostream>
using namespace std;
const int N = 1e6;
int n;
int a[N], b[N], g[N], k[N];
int x, y;
int find()
{
for(int i = n; i >= 1; i--)
{
if(x >= a[i] && y >= b[i] && x <= a[i] + g[i] && y <= b[i] + k[i])
{
return i;
}
}
return -1;
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a[i] >> b[i] >> g[i] >> k[i];
}
cin >> x >> y;
cout << find();
return 0;
}
2、二进制枚举(https://leetcode.cn/problems/subsets/description/)
(1)题目要求是求一个集合的所有子集,这个我们就可以使用二进制枚举。
(2)如果一个集合里面元素的个数为n,那子集的个数则为2^n个,这和 0 ~1<< n - 1的数的二进制设置位是相同的。
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> ret;
int num = nums.size();
for(int i = 0; i < (1 << num); i++)
{
vector<int> temp;
for(int j = 0; j < num; j++)
{
if((i >> j) & 1)
{
temp.push_back(nums[j]);
}
}
ret.push_back(temp);
}
return ret;
}
};
更多推荐


所有评论(0)