递归实现指数型枚举(巧)
原题链接
题目意思简而言之是将{1,2,3……n}中所有的真子集输出。
看了别人的代码写的,递归好巧妙。。。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int a[20];
void dfs(int n,int i,int r){
if(i>n){
for(int j=0;j<r;j++)
printf("%d ",a[j]);
printf("\n");
return;
}
a[r]=i;
dfs(n,i+1,r+1);
dfs(n,i+1,r);
}
int main(){
int n;
scanf("%d",&n);
dfs(n,1,0);
return 0;
}
数的计算(水)
题目来源:洛谷
我们要求找出具有下列性质数的个数(包含输入的自然数nn):
先输入一个自然数nn(n \le 1000n≤1000),然后对此自然数按照如下方法进行处理:
不作任何处理;
在它的左边加上一个自然数,但该自然数不能超过原数的一半;
加上数后,继续按此规则进行处理,直到不能再加自然数为止.
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100010;
int a[1001];
int main(){
int n;
int num=1;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=i/2;j++){
a[i]+=a[j];
}
a[i]+=1;
}
cout<<a[n]<<endl;
return 0;
}
选数(素数,dfs深搜)
#define ll long long
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int x[20],n,k;
bool vis[20];
ll ans=0;
bool isprime(int n){//判断是否质数
int s=sqrt(double(n));
for(int i=2;i<=s;i++){
if(n%i==0)return false;
}
return true;
}
void dfs(int chosen,int sum,int start){
if(chosen==k){
if(isprime(sum))
ans++;
return;
}
for(int i=start;i<n;i++){
if(vis[i]==true)
continue;
vis[i]=true;
dfs(chosen+1,sum+x[i],i+1);// //步数要加一,和也要加
vis[i]=false;
}
return;
}
int main(){
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>x[i];
}
dfs(0,0,0);
cout<<ans<<endl;
return 0;
}