选数
这题的难点就是如何从n个数里面取k个数,也就是要如何利用递归来从数组里面不重复的取数。
我们先要搞明白这个递归函数里面的变量是什么?第一个变量就是step表示走了几步(再先前的很多题目中都是以step的改变作为数组的下标,但是不要被这个思想一直误导),第二个变量就是sum用于计算每次遍历的值,并将这个值进行累加。第三个值就是这个数的后面一个值保证这个数组能够遍历完整个数组(注意再递归函数中第一个for循环就能将整个数组都能遍历完,所以就不需要在主函数中再对递归函数全部遍历一遍,这样就不会造成某些数重复计算)。
代码如下:
#include<iostream>
#include<cmath>
#define N 50200
using namespace std;
int n,k;
int ans=0;
int a[1000000];
int book[10000];
int dx[3]={1,-1};
int tmp=-1;
bool ispear(int sum)
{
int tmp=sqrt(sum);
for(int i=2;i<=tmp;i++)
{
if(sum%i==0)
return false;
}
return true;
}
void dfs(int step,int sum,int x)
{
if(step==k&&ispear(sum))//这里的终止条件一定是step==k要不然就会有些值就会多
{
ans++;
return;
}
for(int i=x;i<=n;i++)
{
dfs(step+1,sum+a[i],i+1);
}
return ;
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
dfs(0,0,1);
cout<<ans<<endl;
return 0;
}
奇怪的电梯
这次就按照bfs写吧,之前按照dfs没有写出来。
坑点:1.这一题每走过一层也是需要标记的,走过的电梯时不能再走一遍的,所以就需设计一个vis数组
2.当输入的进入的电梯层数和需要出去的电梯本来就是一样的就不需要进行下面的操作了,直接输出0就可以了(天知道这两个点坑了我多久)
用一个数组存下每个数组中的值用于方向数组,之前写都是用一个for循环来遍历每一个方向,而在这里就只需要将每一种情况老老实实的写出来就可以了。
然后套用bfs的模板即可,代码如下
#include<iostream>
#define N 10000000
using namespace std;
int a[N];
int vis[N];
struct node
{
int next;
int zhi;
int step;
}q[N];
int n,A,B;
int main()
{
cin>>n>>A>>B;
if(A==B)
{
cout<<"0"<<endl;
return 0;
}
for(int i=1;i<=n;i++)
cin>>a[i];
int head=1;
int tail=1;
q[tail].next=A;
q[tail].zhi=a[A];
q[tail].step=0;
vis[A]=1;
tail++;
while(head<tail)
{
int tx=q[head].next+q[head].zhi;
if(tx==B)
{
printf("%d\n",q[head].step+1);
return 0;
}
if(tx<=n&&tx>=1&&vis[tx]==0)
{
vis[tx]=1;
q[tail].next=tx;
q[tail].zhi=a[tx];
q[tail].step=q[head].step+1;
tail++;
}
tx=q[head].next-q[head].zhi;
if(tx==B)
{
printf("%d\n",q[head].step+1);
return 0;
}
if(tx<=n&&tx>=1&&vis[tx]==0)
{
vis[tx]=1;
q[tail].next=tx;
q[tail].zhi=a[tx];
q[tail].step=q[head].step+1;
tail++;
}
head++;
}
printf("-1\n");
return 0;
}
后面的题目实在搞不出来了