倍数序列
时间限制:1s
内存限制:128M
开始编程
题目描述
【题目描述】
要求找到一个正整数序列,满足序列中所有的数不超过nn,序列长度为mm,且除了第一个数外,所有的数都能被前一个数整除(即是前一个数的倍数)。
我们想要知道这样的序列都有哪些,输出所有满足要求的序列。
输入格式
第一行,两个正整数nn,mm。
输出格式
按字典序从小到大,每行输出一个满足要求的序列,数与数之间用空格分隔。
输入样例#1
输入#1
4 3
输出样例#1
输出#1
1 1 1
1 1 2
1 1 3
1 1 4
1 2 2
1 2 4
1 3 3
1 4 4
2 2 2
2 2 4
2 4 4
3 3 3
4 4 4
【样例说明】
以下13个数列满足条件
1,1,11,1,1;1,1,21,1,2;1,1,31,1,3;1,1,41,1,4;
1,2,21,2,2;1,2,41,2,4;1,3,31,3,3;1,4,41,4,4;
2,2,22,2,2;2,2,42,2,4;2,4,42,4,4;
3,3,33,3,3;4,4,44,4,4。
说明/提示
1 \le n \le 401≤n≤40;1 \le m \le 201≤m≤20
这样是否更好理解?求看;不理解请私信哦
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[10010];
void dfs(int step,int num)
{
if(step>m)
{
for(int i=1;i<=m;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return ;
}
for(int i=0;i<=n-num;i++)
{
a[step]=num+i;
if(a[step]%a[step-1]==0)
dfs(step+1,a[step]);
}
}
int main()
{
a[0]=1;
cin>>n>>m;
dfs(1,1);
return 0;
}
这个存一个栈,然后一个一个加,暴力搜就行了。
比方说 4,3
那么就入栈 3个1.
然后一个一个出。
1,1,1
1出栈
2入栈
1,1,2
然后查是否后面一个取余前面一个等于0
然后一直算到4,4,4
#include <stdio.h>
#include <vector>
using namespace std;
#pragma warning(disable:4996)
bool to_check(vector<int> list, int n) {
for (int i = 0; i < list.size(); i++) {
if (list[i] == n) {
continue;
}
else {
return false;
}
}
return true;
}
// 清除进位后 后面的数 置为1
void clear(vector<int> &list, int n) {
// 如果满位 则进1
int index = list.size() - 1;
for (int i = list.size() - 1; i >= 0; i--) {
if (list[i] == n) {
continue;
}
else {
index = i;
break;
}
}
list[index]++;
for (int i = index + 1; i < list.size(); i++) {
list[i] = 1;
}
}
void add(vector<int> &list, int n) {
int back = list.back();
if (back == n) {
clear(list, n);
}
else {
list.back()++;
}
}
bool is_printf(vector<int> &list) {
bool flag = false;
for (int i = list.size() - 1; i > 0; i--) {
if (list[i] % list[i - 1] == 0 && (list[i] / list[i - 1] != 0)) {
continue;
}
else {
return flag;
}
}
flag = true;
return flag;
}
int main() {
int n = 0, m = 0;
int check;
vector<int> list;
vector<int> res;
// 输入两个数
scanf("%d %d", &n, &m);
check = m - 2;
// 数组初始化
for (int i = 0; i < m; i++) {
list.push_back(1);
}
// 结果数组初始化
for (int i = 0; i < list.size(); i++) {
res.push_back(list[i]);
}
// 当所有值不为 满值时
do {
if (is_printf(res)) {
// 打印一遍数组
for (int i = 0; i < res.size(); i++) {
printf("%d ", res[i]);
}
printf("\n");
}
// 获取末尾的数值
add(res, n);
//
} while (!to_check(res, n));
// 打印一遍数组
for (int i = 0; i < res.size(); i++) {
printf("%d ", res[i]);
}
printf("\n");
}
4 3
1 1 1
1 1 2
1 1 3
1 1 4
1 2 1
1 2 2
1 2 3
1 2 4
1 3 1
1 3 2
1 3 3
1 3 4
1 4 1
1 4 2
1 4 3
1 4 4
2 1 1
2 1 2
2 1 3
2 1 4
2 2 1
2 2 2
2 2 3
2 2 4
2 3 1
2 3 2
2 3 3
2 3 4
2 4 1
2 4 2
2 4 3
2 4 4
3 1 1
3 1 2
3 1 3
3 1 4
3 2 1
3 2 2
3 2 3
3 2 4
3 3 1
3 3 2
3 3 3
3 3 4
3 4 1
3 4 2
3 4 3
3 4 4
4 1 1
4 1 2
4 1 3
4 1 4
4 2 1
4 2 2
4 2 3
4 2 4
4 3 1
4 3 2
4 3 3
4 3 4
4 4 1
4 4 2
4 4 3
4 4 4
然后要做的就是筛选res中满足所有条件的部分。
显然的,在73行加条件 对输出语句加以限制就可以完成了。
用递归算法
你题目的解答代码如下:(如有帮助,望采纳!谢谢! 点击我这个回答右上方的【采纳】按钮)
#include<stdio.h>
int pf(int a[],int n,int m,int t,int k)
{
int i,j;
for (i=t; i<=n; i+=t){
a[k] = i;
if (k<m-1) {
pf(a,n,m,i,k+1);
} else {
for(j=0;j<m;j++)
{
printf("%d ",a[j]);
}
printf("\n");
}
}
return 0;
}
int main()
{
int i,n,m;
scanf("%d%d",&n,&m);
int a[m];
pf(a,n,m,1,0);
return 0;
}