【搜索练习】【二】

1617: 阿克曼函数(递归)


 

时间限制: 1 Sec  内存限制: 128 MB
提交: 135  解决: 91
[提交][状态][讨论版]

题目描述

阿克曼( Ackmann) 函数 A(x, y) 中, x, y 定义域是非负整数, 函数值定义为:

 

 

输入

输入两个数,表示m和n。 两个数均不超过10。

输出

输出一个数,表示结果(在longint范围内 )

样例输入

1 1

样例输出

3

提示

 

来源

递归


帮助理解递归 按题目意思直接打就好 

//不要抄错题目条件不要问我怎么知道的QAQ

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
int x,y;
long int ack(int m,int n)
{
    if(m==0)return n+1;
    if(m!=0&&n==0)ack(m-1,1);
    if(m!=0&&n!=0)ack(m-1,ack(m,n-1));
}
int main()
{
    cin>>x>>y;
    cout<<ack(x,y);
    puts("");
    return 0;
}
View Code

P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib

题目描述

农民约翰的母牛总是产生最好的肋骨。你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们。农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数字都组成一个质数,举例来说: 7 3 3 1 全部肋骨上的数字 7331是质数;三根肋骨 733是质数;二根肋骨 73 是质数;当然,最后一根肋骨 7 也是质数。 7331 被叫做长度 4 的特殊质数。写一个程序对给定的肋骨的数目 N (1<=N<=8),求出所有的特殊质数。数字1不被看作一个质数。

输入输出格式

输入格式:

 

单独的一行包含N。

 

输出格式:

 

按顺序输出长度为 N 的特殊质数,每行一个。

 

输入输出样例

输入样例#1:
4
输出样例#1:
2333
2339
2393
2399
2939
3119
3137
3733
3739
3793
3797
5939
7193
7331
7333
7393

说明

题目翻译来自NOCOW。

USACO Training Section 1.5


暴力一点的搜索的话 是这么玩的 会T一个点

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
int n;
int a[10];
bool zs(int res)
{
    if(res==1)return 0;
    int pd=sqrt(res);
    for(int i=2;i<=pd;++i)if(res%i==0)return 0;
    return 1;
}
void print()
{
    if(a[1]==1||a[1]==0)return;
    int sum=0;
    for(int i=1;i<=n;++i)
    {
        sum=sum*10+a[i];
        if(!zs(sum))return;
    }
    cout<<sum;
    puts("");
}
void dfs(int cur)
{
    if(cur==n+1)print();
    else for(int i=0;i<=9;++i)
    {
            a[cur]=i;
            dfs(cur+1);
    }
}
int main()
{
    cin>>n;
    dfs(1);
    puts("");
    return 0;
}
View Code
 当n=8时
你的状态数是10的8次方
肯定T
那么我们就需要一个超强力的剪枝

你在dfs的时候记录下当前的数字 如果不是质数就直接return 也就是说不需要a数组了记录一个sum就好 

  

 

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
int n;
int minn=1;
int a[10];
bool zs(int res)
{
    if(res==0)return 1;
    if(res==1)return 0;
    int pd=sqrt(res);
    for(int i=2;i<=pd;++i)if(res%i==0)return 0;
    return 1;
}
void print(int s)
{
    if(s<minn)return;
    cout<<s;
    puts("");
}
void dfs(int cur,int he)
{
    if(!zs(he))
    {
        return;
    }
    if(cur==n+1)print(he);
    else for(int i=0;i<=9;++i)
    {
//        he=he*10+i;
        dfs(cur+1,he*10+i);
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<n;++i)minn*=10;
    dfs(1,0);
    puts("");
    return 0;
}
View Code

注意:

 判断这个要在for外面哦
不然有的可能的解都被你ban掉了
错过正解啦QWQ

 

1152: 细胞问题

时间限制: 1 Sec  内存限制: 128 MB
提交: 218  解决: 117
[提交][状态][讨论版]

题目描述

一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。

如:阵列

0234500067
1034560500
2045600671
0000000089  
有4个细胞


输入

第一行 :两个数字M N (1<=M<=50 1<=N<80)表示该阵列有M行N列,从第2行到第M+1行 每行有连续的N个字符。

输出

一行: 细胞个数。

样例输入

4 10
0234500067
1034560500
2045600671
0000000089

样例输出

4

提示

 

来源

广度搜索★


注意他们是字符呀 不要搞成int的数组了 

反例:

 如果我要输入
3 3 
111
101
111
 他会把第一行的111当成一百一十一来看吗
因为是粘在一起的 
所以输入时候就直接把一行当成一个字符串输入就好啦
深搜版:
 
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

int m,n;
int ans=0;
char a[100][100];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
void dfs(int x,int y)
{
    if(x>m||x<1||y>n||y<1)return;
    a[x][y]='0';
    for(int i=0;i<4;++i)
    {
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(a[nx][ny]!='0')dfs(nx,ny);
    }
}
int main()
{
    cin>>m>>n;
    for(int i=1;i<=m;++i)
    {
        for(int j=1;j<=n;++j)
        {
            cin>>a[i][j];//puts("");cout<<a[i][j];
        }
    }
    for(int i=1;i<=m;++i)
    {
        for(int j=1;j<=n;++j)
        {
            if(a[i][j]!='0')
            {
                dfs(i,j);
                ++ans;
            }
        }
    }
    cout<<ans;
    puts("");
    return 0;
}
View Code

宽搜版:

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;
string s;
int m,n;
int a[100][100],now[5000][4];
int dx[5]={1,-1,0,0};
int dy[5]={0,0,-1,1};
int ans=0;
void bfs(int p,int q)
{
    int x,y,w=1,t=1;
    ++ans;
    a[p][q]=0;
    now[1][1]=p;
    now[1][2]=q;
    do
    {
        for(int i=0;i<4;++i)
        {
            x=dx[i]+now[t][1];
            y=dy[i]+now[t][2];
            if(x>0&&x<=m&&y>0&&y<=n&&a[x][y]!=0)
            {
                ++w;
                now[w][1]=x;
                now[w][2]=y;
                a[x][y]=0;
            }
        }
        ++t;
    }while(t<=w);
}
int main()
{
    cin>>m>>n;
    for(int i=1;i<=m;++i)
    {
        cin>>s;
        for(int j=0;j<n;++j)a[i][j+1]=s[j]-'0';
    }
    for(int i=1;i<=m;++i)
    {
        for(int j=1;j<=n;++j)
        {
            if(a[i][j]!=0)
            {
                bfs(i,j);
            }
        }
    }
    cout<<ans;
    puts("");
    return 0;
}
View Code

 

 


 

 

 

 

 

 

posted @ 2017-06-27 21:53  pandaB  阅读(336)  评论(0编辑  收藏  举报