描述
正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。
数据范围:1≤a,b≤100000
输入描述:输入两个正整数A和B。
输出描述:输出A和B的最小公倍数。
示例1
输入:
5 7
输出:
35
示例2
输入:
2 4
输出:
4
思路
先获取两个数的最大公因数p,最小公倍数是m*n/p
代码
#include
using namespace std;
int getMaxFactor(int m, int n) {
int res = min(m,n);
while (res > 1) {
if(m % res == 0 && n % res == 0) break;
res--;
}
return res;
}
int getMinMultiple(int m, int n) {
int k = getMaxFactor(m, n);
return m*n/k;
}
int main() {
int m;
int n;
cin >> m >> n;
cout << getMinMultiple(m, n);
return 0;
}
描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的 N ( N 为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。
输入:
有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。
输出:
输出一个整数 K ,表示你求得的“最佳方案”组成“素数伴侣”的对数。
数据范围:1≤n≤100,输入的数据大小满足 2≤val≤30000
输入描述:输入说明:1 输入一个正偶数 n;2 输入 n 个整数
输出描述:求得的“最佳方案”组成“素数伴侣”的对数。
示例1
输入:
4
2 5 6 13
输出:
2
示例2
输入:
2
3 6
输出:
0
思路
概念
二分图
顶点分为两个不想交的集合(U,V)
集合内的点两两不相连
二分图匹配
增广路径:二分图的匹配中,有一条路径的首尾是非匹配点,路径中其他点均是匹配点,这条路径就是一条增广路径。(即一条首尾相连的路径)
匈牙利算法
变量:
思路
参考:https://www.cnblogs.com/techflow/p/13522712.html
https://zhuanlan.zhihu.com/p/534989336
#include
using namespace std;
#include
class Solution
{
private:
vector> allPair;
vector evVis;
vector odVis;
vector visited;
public:
Solution(vector ev, vector od) {
int m = ev.size();
int n = od.size();
allPair.resize(m, vector (n, false));
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(isPrime(ev[i] + od[j])) allPair[i][j] = true;
}
}
evVis.resize(m, -1);
odVis.resize(n, -1);
}
bool isPrime(int num) {
for(int i = 2; i < num/2; i++)
if(num % i == 0) return false;
return true;
}
int dfs(int i) {
for(int j = 0; j < odVis.size(); j++) {
if(!visited[j] && allPair[i][j]) {
visited[j] = true;
if(odVis[j] == -1 || dfs(odVis[j])) {
evVis[i] = j;
odVis[j] = i;
return 1;
}
}
}
return 0;
}
int getCouple() {
int res = 0;
for(int i = 0; i < evVis.size(); i++) {
visited.assign(odVis.size(),0);
res += dfs(i);
}
return res;
}
};
int main() {
int n;
cin >> n;
vector nums(n);
vector ev,od;
int num;
for(int i = 0; i < n; i++) {
cin >> num;
if(num % 2 == 0)
od.push_back(num);
else
ev.push_back(num);
}
Solution sol(ev, od);
cout << sol.getCouple() << endl;
return 0;
}
描述
任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对。
数据范围:输入的数据满足4≤n≤1000
输入描述:输入一个大于2的偶数
输出描述:从小到大输出两个素数
示例1
输入:
20
输出:
7
13
示例2
输入:
4
输出:
2
2
思路
从一半开始从大到小遍历,判断是否为素数
代码
#include
using namespace std;
bool isPrime(int n) {
for(int i = 2; i < n/2; i++)
if(n%i == 0) return false;
return true;
}
void getPrimeCouple(int n) {
int a = n/2;
int b;
while(a) {
b = n - a;
if(!isPrime(a)){
a--;
continue;
}
if(isPrime(b)) break;
a--;
}
cout << a << endl;
cout << b << endl;
}
int main() {
int n;
cin >> n;
getPrimeCouple(n);
return 0;
}
描述
在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1
示例 1:
输入:grid = [[2,1,1],[1,1,0],[0,1,1]]
输出:4
示例 2:
输入:grid = [[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。
示例 3:
输入:grid = [[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 10
grid[i][j] 仅为 0、1 或 2
思路
使用bfs算法,先遍历烂橘子的周围,step++,直到遍历完为止
代码
#include
using namespace std;
#include
#include
class Solution {
int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
public:
int orangesRotting(vector>& grid) {
int step = -1;
queue> que;
bool isOnlyZero = true;
for (auto ls:grid)
for (auto x:ls)
if (x) isOnlyZero = false;
if(isOnlyZero) return 0;
for (int i = 0; i < grid.size(); i++)
for (int j = 0; j < grid[i].size(); j++)
if (grid[i][j] == 2) que.emplace(i,j);
while (!que.empty()) {
int size = que.size();
step++;
while(size--) {
auto [x, y] = que.front();
que.pop();
for(int i = 0; i < 4; i++) {
int nx = x + dirs[i][0];
int ny = y + dirs[i][1];
if (nx >= 0 && nx < grid.size() && ny >= 0 && ny < grid[nx].size() && grid[nx][ny] == 1) {
que.emplace(nx, ny);
grid[nx][ny] = 2;
}
}
}
}
for (auto ls:grid)
for (auto x:ls)
if (1 == x)
return -1;
return step;
}
};
int main() {
vector> grid;
grid.push_back({2,1,1});
grid.push_back({0,1,1});
grid.push_back({1,0,1});
Solution sol;
cout << sol.orangesRotting(grid) << endl;
return 0;
}
描述
给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。
示例 1:
输入:n = 10
输出:4
解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
示例 2:
输入:n = 0
输出:0
示例 3:
输入:n = 1
输出:0
提示:
0 <= n <= 5 * 106
思路
代码
#include
using namespace std;
#include
// class Solution {
// public:
// int countPrimes(int n) {
// int res = 0;
// bool isPrimes = true;
// for (int i = 2; i < n; i++) {
// isPrimes = true;
// for (int j = 2; j * j <= i; j++) {
// if(i % j == 0) isPrimes = false;
// }
// if (isPrimes){
// res++;
// printf("%d\n",i);
// }
// }
// return res;
// }
// };
class Solution {
public:
int countPrimes(int n) {
int res = 0;
vector isPrimes(n,true);
for (int i = 2; i * i < n; i++) {
if (isPrimes[i])
for (int j = i * i; j < n; j += i)
isPrimes[j] = false;
}
for (int i = 2; i < n; i++)
if (isPrimes[i]) res++;
return res;
}
};
int main() {
int n = 20;
Solution sol;
cout << sol.countPrimes(n) << endl;
return 0;
}
描述
信息社会,有海量的数据需要分析处理,比如公安局分析身份证号码、 QQ 用户、手机号码、银行帐号等信息及活动记录。
采集输入大数据和分类规则,通过大数据分类处理程序,将大数据分类输出。
数据范围:1≤I,R≤100 ,输入的整数大小满足 0≤val≤2^31−1
输入描述:一组输入整数序列I和一组规则整数序列R,I和R序列的第一个整数为序列的个数(个数不包含第一个整数);整数范围为0~(2^31)-1,序列个数不限
输出描述:从R依次中取出R,对I进行处理,找到满足条件的I:
I整数对应的数字需要连续包含R对应的数字。比如R为23,I为231,那么I包含了R,条件满足 。
按R从小到大的顺序:
(1)先输出R;
(2)再输出满足条件的I的个数;
(3)然后输出满足条件的I在I序列中的位置索引(从0开始);
(4)最后再输出I。
附加条件:
(1)R需要从小到大排序。相同的R只需要输出索引小的以及满足条件的I,索引大的需要过滤掉
(2)如果没有满足条件的I,对应的R不用输出
(3)最后需要在输出序列的第一个整数位置记录后续整数序列的个数(不包含“个数”本身)
序列I:15,123,456,786,453,46,7,5,3,665,453456,745,456,786,453,123(第一个15表明后续有15个整数)
序列R:5,6,3,6,3,0(第一个5表明后续有5个整数)
输出:30, 3,6,0,123,3,453,7,3,9,453456,13,453,14,123,6,7,1,456,2,786,4,46,8,665,9,453456,11,456,12,786
说明:
30----后续有30个整数
3----从小到大排序,第一个R为0,但没有满足条件的I,不输出0,而下一个R是3
6--- 存在6个包含3的I
0--- 123所在的原序号为0
123--- 123包含3,满足条件
示例1
输入:
15 123 456 786 453 46 7 5 3 665 453456 745 456 786 453 123
5 6 3 6 3 0
输出:
30 3 6 0 123 3 453 7 3 9 453456 13 453 14 123 6 7 1 456 2 786 4 46 8 665 9 453456 11 456 12 786
说明:
将序列R:5,6,3,6,3,0(第一个5表明后续有5个整数)排序去重后,可得0,3,6。
序列I没有包含0的元素。
序列I中包含3的元素有:I[0]的值为123、I[3]的值为453、I[7]的值为3、I[9]的值为453456、I[13]的值为453、I[14]的值为123。
序列I中包含6的元素有:I[1]的值为456、I[2]的值为786、I[4]的值为46、I[8]的值为665、I[9]的值为453456、I[11]的值为456、I[12]的值为786。
最后按题目要求的格式进行输出即可。
思路
代码
#include
using namespace std;
#include
#include
vector sortAndDel(vector nums) {
sort(nums.begin(), nums.end());
if(nums.size() <= 1) return nums;
int pre = nums[0];
vector res;
res.push_back(pre);
for(int i = 1; i < nums.size(); i++) {
if(nums[i] != pre) {
pre = nums[i];
res.push_back(pre);
}
}
return res;
}
bool isRight(int x, int y) {
string a = to_string(x);
string b = to_string(y);
for(int i = 0; i < a.size(); i++)
if(a[i] == b[0] && !a.substr(i,b.size()).compare(b))
return true;
return false;
}
//取出R[i],对I进行处理,找到满足条件的I
//条件:I证书对应的数字需要连续包含R[i],对I进行处理
vector>> getRes(vector I, vector R) {
//R[i]从小到大的顺序
R = sortAndDel(R);
vector>> res(R.size(), vector>());
for(int i = 0; i < R.size(); i++) {
for(int j = 0; j < I.size(); j++) {
if(isRight(I[j],R[i])) res[i].push_back({j, I[j]});
}
}
int num = 0;
for(int i = 0; i < res.size(); i++) {
if(res[i].size()) num = num + 2 + 2 * res[i].size();
}
printf("%d ",num);
for(int i = 0; i < res.size(); i++) {
if(!res[i].size()) continue;
//先输出R[i] 输出满足条件的I的个数
printf("%d %d ", R[i], res[i].size());
for(int j = 0; j < res[i].size(); j++) {
//输出满足条件的I在I序列中的位置索引 输出I
printf("%d %d ",res[i][j].first,res[i][j].second);
}
}
printf("\n");
return res;
}
int main() {
int m;
cin >> m;
vector I(m);
for(int i = 0; i < m; i++)
cin >> I[i];
int n;
cin >> n;
vector R(n);
for(int i = 0; i < n; i++)
cin >> R[i];
getRes(I,R);
return 0;
}