• 假期训练八(poj-2965递归+枚举,hdu-2149,poj-2368巴什博奕)


    题目一(poj-2965):传送门

    思路:递归+枚举,遍历每一种情况,然后找出最小步骤的结果,与poj-1753类似。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    //#include<ctime>
    using namespace std;
    int x[20],y[20],xx[20],yy[20],ans=99;
    char str[20];
    int a[20][20];
    void turn(int len)
    {
        int x=len/4,y=len%4;
        for(int i=0;i<4;i++)
        {
            a[x][i]=!a[x][i];
            a[i][y]=!a[i][y];
        }
        a[x][y]=!a[x][y];
    }
    bool pd()
    {
        for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
            if(a[i][j]!=1) return false;
        return true;
    }
    void dfs(int len,int num) //要用len,否则时间超限。 
    {
        if(pd())
        {
            if(ans>num)
            {
                ans=num;
                for(int i=1;i<=ans;i++)
                {
                    xx[i]=x[i];
                    yy[i]=y[i];
                }
            }
            return ;
        }
        if(len>=16) return ; //基准情形 
        dfs(len+1,num);//先搜索 
        turn(len); //再变化 
        x[num+1]=len/4+1;
        y[num+1]=len%4+1;
        dfs(len+1,num+1); //记得回溯。 
        turn(len);
    }
    int main(void)
    {
        int i,j;
        //int st=clock(),ed;
        for(i=0;i<4;i++)
        {
            scanf("%s",str);
            for(j=0;j<4;j++) 
            if(str[j]=='-') a[i][j]=1;
            else a[i][j]=0;
        }
        dfs(0,0);
        printf("%d
    ",ans);
        for(i=1;i<=ans;i++)
        {
            printf("%d %d
    ",xx[i],yy[i]);
        }
        //ed=clock();
        //printf("time==%d
    ",ed-st);
        return 0;
    }
    
    
    
    //原来用x,y作为参数,时间超限 
    /*#include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<ctime>
    using namespace std;
    int a[10][10],mi=99;
    int x[100],y[100],cnt=0;
    int xx[100],yy[100];
    char str[10];
    bool pd()
    {
        for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
            if(a[i][j]==1) return false;
        return true;
    }
    void turn(int x,int y)
    {
        for(int i=0;i<4;i++)
        {
            a[x][i]=!a[x][i];
            a[i][y]=!a[i][y];
        }
        a[x][y]=!a[x][y];
    }
    void dfs(int x1,int y1,int num)
    {
        if(pd())
        {
            if(mi>num)
            {
                mi=num;
                for(int i=1;i<=num;i++)
                {
                    xx[i]=x[i];
                    yy[i]=y[i];
                }
            }
            return ;
        }
        if(x1*y1>9) return ;
        
        if(y1==3) dfs(x1+1,0,num);
        else dfs(x1,y1+1,num);
        turn(x1,y1);
        x[num+1]=x1+1;y[num+1]=y1+1;
        if(y1==3) dfs(x1+1,0,num+1);
        else dfs(x1,y1+1,num+1);
        turn(x1,y1);
    }
    int main(void)
    {
        int i,j;
        int st,ed;
        st=clock();
        for(i=0;i<4;i++)
        {
            scanf("%s",str);
            for(j=0;j<4;j++)
            if(str[j]=='+') a[i][j]=1;
            else a[i][j]=0;
        }
        dfs(0,0,0);
        printf("%d
    ",mi);
        for(i=1;i<=mi;i++)
        {
            printf("%d %d
    ",xx[i],yy[i]);
        }
        ed=clock();
        printf("time==%d
    ",ed-st);
        return 0;
    }*/
    View Code

    题目二(poj-2368):传送门

    思路:巴什博奕,求出使后者成功的最小的L,就是求n的非一最小因子-1,要用素数筛法,否则超时。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 100100;
    int a[maxn];
    int main(void)
    {
        int n,i,m;
        while(~scanf("%d",&n))
        {
            int len=0;
            for(i=1;i*i<=n;i++)
            {
                if(n%i==0)
                {
                    a[len++]=i;
                    a[len++]=n/i;
                }
            }
            sort(a,a+len);
            int fg=0;
            for(i=0;i<len;i++)
            {
                if(a[i]>=3)
                {
                    fg=1;
                    printf("%d
    ",a[i]-1);
                    break;
                }
            }
            if(fg==0) printf("0
    ");
        }
        return 0;
    } 
    View Code

    总结:递归不要忘记确立分清楚基准情况,先搜索,再回溯。

  • 相关阅读:
    算法时间复杂度
    C#箴言:定义常量的两种方法
    Java对象池示例
    一种轻量级对象池的设计与实现
    游戏功能逻辑优化
    c#二维数组传递与拷贝
    一个高效的A-star寻路算法(八方向)(
    3DMAX 烘培技术
    Unity3D脚本生命周期
    Unity 组件
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10266531.html
Copyright © 2020-2023  润新知