USACO1.3.4牛式

题目

思路

这个一看就是9^5的一个暴力枚举嘛 ,但是判断是一如既往的恼火,代码应该可以多用几个函数极大的简化,就是for用递归while再用一个判断
题目不解释样例我很恼火

代码

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,cnt;
int a,b,c,d,e;
int x[15];
int vis[15];
void Init()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x[i]);
        vis[x[i]]++;
    }
}
bool calc()
{
    int x1=a*100+b*10+c,x2=d*10+e;
    int y1=e*x1,y2=d*10*x1;
    int z=y1+y2;
    y2/=10;
    if(z>=10000||y2>=10000||y1>=1000)
        return 0;
    while(x1)
    {
        if(vis[x1%10]==0)
            return 0;
        x1/=10;
    }
    while(x2)
    {
        if(vis[x2%10]==0)
            return 0;
        x2/=10;
    }
    while(y1)
    {
        if(vis[y1%10]==0)
            return 0;
        y1/=10;
    }
    while(y2)
    {
        if(vis[y2%10]==0)
            return 0;
        y2/=10;
    }
    while(z)
    {
        if(vis[z%10]==0)
            return 0;
        z/=10;
    }
    return 1;
}
int main()
{
    //freopen("in.txt","r",stdin);
    Init();
    for(int a1=1;a1<=n;a1++)
        for(int b1=1;b1<=n;b1++)
            for(int c1=1;c1<=n;c1++)
                for(int d1=1;d1<=n;d1++)
                    for(int e1=1;e1<=n;e1++)
                    {
                        a=x[a1];
                        b=x[b1];
                        c=x[c1];
                        d=x[d1];
                        e=x[e1];
                        if(calc())
                            cnt++;
                    }


    cout<<cnt<<endl;
    return 0;
}

收获

1、注意下标和元素的对应关系,这个不留心的话就容易搞错
2、相同功能的内容尝试写函数,比Ctrlc+Ctrlv肯定是美观很多
3、自己要捋顺各种变量的含义,可以写下来,不耽误时间
4、回溯算法比较耗时间( 可能是函数 事实证明不是,甚至用了函数快了一点),因为有一个入栈和返回的过程,理论上比直接循环慢一倍,但是 (好看啊) 好写呀,还很多重(或者n重)循环你怎么搞?
第四点哪里来的呢?..






番外

像我这种强迫症怎么可能放任代码这么难看呢?哈哈哈。。。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,cnt;
int a[10];
int x[15];
int vis[15];
void Init()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x[i]);
        vis[x[i]]++;
    }
}
bool jud(int x)
{
    while(x)
    {
        if(vis[x%10]==0)
            return 0;
        x/=10;
    }
    return 1;
}
bool calc()
{
    int x1=a[1]*100+a[2]*10+a[3],x2=a[4]*10+a[5];
    int y1=a[4]*x1,y2=a[5]*10*x1;
    int z=y1+y2;
    y2/=10;
    if(z>=10000||y2>=10000||y1>=1000)
        return 0;
    return jud(x1)&&jud(x2)&&jud(y1)&&jud(y2)&&jud(z);
}
void run(int i)
{
    if(i>5)
    {
        cnt+=calc();
        return;
    }
    for(int j=1;j<=n;j++)
    {
        a[i]=x[j];
        run(i+1);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    Init();
    run(1);
    cout<<cnt<<endl;
    return 0;
}

好看多了嘛。

end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值