游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2037|回复: 3

可以加 减 乘 除 算24的程序源!

[复制链接]

2

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2004-3-1 18:20:00 | 显示全部楼层 |阅读模式
和媳妇玩算24的扑克游戏,(轮流摸牌,看谁的牌点数加减乘除得24,每一张仅能用一次,也必须用一次) 有时怎么都算不出来。于是无聊写了这程序!
两个版本,版本一属于涂鸦可以很好得工作,版本二是精练后得。
下面是源代码,在vc.net 2003 下编译通过
#include <windows.h>
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>

#define MAX_INPUT 32

int g_value = 24;

/*
//第一个版本
bool is24_print( int buf[],int op[],int len ){
        int i;
        int value = buf[0];
        for( i = 1;i < len;i++ ){
                switch( op[i-1] ){
                        case 0:
                        value += buf;
                        break;
                        case 1:
                        value -= buf;
                        break;
                        case 2:
                        value *= buf;
                        break;
                        case 3:
                        if( value % buf == 0 )
                                value /= buf;
                        else
                                return false;
                        break;
                        default:
                                std::cout<<"error op:"<<op[i-1]<<std::endl;
                                return false;
                }
        }
        if( value == g_value ){
//                value = buf[0];
//                std::cout << "[";
//                std::cout << buf[0];
//                for( i = 1;i < len;i++ ){
//                        switch( op[i-1] ){
//                                case 0:
//                                std::cout<< "+";
//                                value += buf;
//                                break;
//                                case 1:
//                                std::cout<< "-";
//                                value -= buf;
//                                break;
//                                case 2:
//                                std::cout<< "*";
//                                value *= buf;
//                                break;
//                                case 3:
//                                std::cout<< "/";
//                                value /= buf;
//                                break;
//                        }
//                        std::cout << buf;
//                        std::cout << "=" << value << "  " << value;
                }
                std::cout << "]" << std::endl;
                return true;
        }
        return false;
}

void jprint( int b[],int len ){
        int i,value = 0;
        int buf[MAX_INPUT];
        int op[MAX_INPUT];

        for( i = 0;i < len;i++ ){
                buf = b[2*i];
                if( i < len-1 )
                        op = b[2*i+1];
        }
        value = buf[0];
        std::cout << "[";
        std::cout << buf[0];
        for( i = 1;i < len;i++ ){
                switch( op[i-1] ){
                        case 0:
                        std::cout<< "+";
                        value += buf;
                        break;
                        case 1:
                        std::cout<< "-";
                        value -= buf;
                        break;
                        case 2:
                        std::cout<< "*";
                        value *= buf;
                        break;
                        case 3:
                        std::cout<< "/";
                        value /= buf;
                        break;
                }
                std::cout << buf;
                std::cout << "=" << value << "  " << value;
        }
        std::cout << "]" << std::endl;
}

void n_for_( int layer,int buf[],int n,int inx[],int m,void (*func)( int buf[],int n,void* pd),void* pp ){
        if( layer == 0 )std::cout << "[" << m << "]";
        for( int i = 0;i < m;i++ ){
                if( layer == 0 ){
                        std::cout << " " << i;
                }
                buf[layer] = inx[layer];
                for( int j = layer+1;j < n;j++ )
                        inx[j] = 0;
                if( layer == n-1 )
                        func( buf,n,pp );
                else
                        n_for_( layer+1,buf,n,inx,m,func,pp );
                inx[layer]++;
        }
        if( layer == 0 )
                std::cout << " " << m << " ok!" << std::endl;
}

bool is_bad( int buf[],int n ){
        for( int i = 0;i < n;i++ ){
                for( int j = 0;j < n;j++ ){
                        if( i != j && buf == buf[j] )
                                return true;
                }
        }
        return false;
}

bool g_is_bad;

void my_back( int buf[],int n,void* pp ){
        std::list<int>* pst;
        pst = (std::list<int>*)pp;
        if( g_is_bad && is_bad( buf,n ) )
                return;
        for( int i = 0;i < n;i++ ){
                pst->push_back( buf );
        }
}

void getZuHe( int n,int m,std::list<int>& st ){
        int buf[MAX_INPUT];
        int inx[MAX_INPUT];

        for( int i = 0;i < n;i++ )
                inx = 0;
       
        n_for_( 0,buf,n,inx,m,my_back,&st );
}

bool iseq( int buf[],int buf2[],int len ){
        for( int i = 0;i < len;i++ ){
                if( buf != buf2 )return false;
        }
        return true;
}

bool ishava( int buf[],int op[],int len,std::list<int>* pst ){
        int inx = 0;
        int buf2[2*MAX_INPUT];
        int buf3[2*MAX_INPUT];

        for( int j = 0;j < len;j++ ){
                buf2[2*j] = buf[j];
                if( j < len - 1)
                        buf2[2*j+1] = op[j];
        }

        for( std::list<int>::iterator i = pst->begin();i != pst->end();i++ ){
                buf3[inx] = *i;
                if( inx == 2*len - 2 ){
                        if( iseq( buf2,buf3,2*len-1 ) ){
                                return true;
                        }
                }
                inx++;
                if( inx == 2*len-1 )inx = 0;
        }
        return false;
}

int main(int argc, char* argv[])
{
        int const_buf[MAX_INPUT];
        int buf[MAX_INPUT];
        int buf2[MAX_INPUT];
        int op[MAX_INPUT];
        int inx,inxj;
        int len,count;
        DWORD t0 = GetTickCount();
        if( argc == 1 ){
                len = 5;
                const_buf[0] = 13;
                const_buf[1] = 13;
                const_buf[2] = 3;
                const_buf[3] = 4;
                const_buf[4] = 8;
        }else{
                len = argc-1;
                for( int i = 1;i < argc;i++ ){
                        const_buf[i-1] = atoi( argv );
                }
        }

        if( len < 2 || len > 8 ){
                std::cout << "error param!" << std::endl;
                return 0;
        }

        {
                std::cout << "input: ";
                for( int i = 0;i < len;i++ ){
                        std::cout << const_buf << "  ";
                }
                std::cout << std::endl;
        }
        std::list<int> stop;
        std::list<int> st;
        std::list<int> sst;
        std::list<int> stmin;
        g_is_bad = false;
        getZuHe( len-1,4,stop );
        g_is_bad = true;
        getZuHe( len,len,st );


        inx = 0;
        inxj = 0;
        {
                std::list<int> temp;
                std::cout << "1.[" << st.size() << "] - ";
                for( std::list<int>::iterator j = st.begin();j != st.end();j++ ){
                        buf[inxj] = const_buf[*j];
                        temp.push_back( *j );
                        if( inxj == len-1 ){
                                bool is_same = false;
                                inx = 0;
                                for( std::list<int>::iterator i = sst.begin();i != sst.end();i++ ){
                                        buf2[inx] = const_buf[*i];
                                        if( inx == len-1 ){
                                                //if( memcmp( buf,buf2,sizeof(int)*len ) == 0 ){
                                                if( iseq( buf,buf2,len ) ){
                                                        is_same = true;
                                                        break;
                                                }
                                        }
                                        inx++;
                                        if( inx == len ) inx = 0;
                                }
                                if( is_same == false ){
                                        for( std::list<int>::iterator i = temp.begin();i != temp.end();i++ ){
                                                sst.push_back( *i );
                                        }
                                        temp.clear();
                                }
                        }
                        inxj++;
                        if( inxj == len )inxj = 0;
                }
        }

        inx = 0;
        inxj = 0;
        count = 0;
        {
                std::cout << "2.[" << sst.size() << "] - ";
                for( std::list<int>::iterator i = stop.begin();i != stop.end();i++ ){
                        op[inx] = *i;
                        if( inx == len-2 ){
                                for( std::list<int>::iterator j = sst.begin();j != sst.end();j++ ){
                                        buf[inxj] = const_buf[*j];
                                        if( inxj == len-1 ){
                                                if( is24_print( buf,op,len ) ){
                                                        if( !ishava( buf,op,len,&stmin ) ){
                                                                stmin.push_back( buf[0] );
                                                                for( int i = 1;i < len;i++ ){
                                                                        stmin.push_back( op[i-1] );
                                                                        stmin.push_back( buf );
                                                                }
                                                                count++;
                                                        }
                                                }
                                        }
                                        inxj++;
                                        if( inxj == len )inxj = 0;
                                }
                        }
                        inx++;
                        if( inx == len-1 )inx = 0;
                }
                std::cout << "count = " << count << std::endl;
        }
        {
                int bb[2*MAX_INPUT];
                inx = 0;
                std::cout << "3.[" << stmin.size() << "]"<<std::endl;
                for( std::list<int>::iterator i = stmin.begin();i != stmin.end();i++ ){
                        bb[inx] = *i;
                        if( inx == 2*len-2){
                                jprint( bb,len );
                        }
                        inx++;
                        if( inx == 2*len-1 )inx = 0;
                }
        }
        std::cout << "use time: " << GetTickCount() - t0 << std::endl;
        return 0;
}
*/
//第二个版本
class for_m{
public:
        int n;
        int m;
        std::vector<int> table;

        for_m( int _n,int _m ){
                n = _n;
                m = _m;
                for( int i = 0;i < n;i++ )
                        table.push_back( 0 );
        }
        bool next(){
                table[0]++;
                for( int i = 0;i < n;i++ ){
                        if( table == m ){
                                table = 0;
                                if( i+1 < n )
                                        table[i+1]++;
                                else
                                        return false;
                        }else return true;
                }
                return true;
        }
};

inline bool is_g_value_print( std::vector<int>& inx,std::vector<int>& s,std::vector<int>& o ){
        std::vector<int>::iterator k = s.begin();
        int value = *(k + *inx.begin());
       
        for( std::vector<int>::iterator j = o.begin(), i = inx.begin()+1;i != inx.end();i++,j++ ){
                switch( *j ){
                        case 0:
                        value += *(k + *i);
                        break;
                        case 1:
                        value -= *(k + *i);
                        break;
                        case 2:
                        value *= *(k + *i);
                        break;
                        case 3:
                        if( value % *(k + *i) == 0 )
                                value /= *(k + *i);
                        else
                                return false;
                        break;
                        default:
                                std::cout<<"error op:"<< *j <<std::endl;
                                return false;
                }
        }
        if( value == g_value ){
                value = *(k + *inx.begin());
                std::cout << "[";
                std::cout << value;
                for( std::vector<int>::iterator j = o.begin(), i = inx.begin()+1;i != inx.end();i++,j++ ){
                        switch( *j ){
                                case 0:
                                        std::cout << "+";
                                value += *(k + *i);
                                break;
                                case 1:
                                        std::cout << "-";
                                value -= *(k + *i);
                                break;
                                case 2:
                                        std::cout << "*";
                                value *= *(k + *i);
                                break;
                                case 3:
                                        std::cout << "/";
                                value /= *(k + *i);
                                break;
                        }
                        std::cout << *(k + *i);
                        std::cout << "=" << value << " " << value;
                }
                std::cout << "]" << std::endl;
                return true;
        }
        return false;
}

int main( int argc,char* argv[] ){
        std::vector<int>  minput;
        std::vector<int>  inx;
        DWORD t0 = GetTickCount();
        int count = 0;

        if( argc < 3 )return -1;
        for( int i = 1;i < argc;i++ ){
                minput.push_back( atoi( argv ) );
                inx.push_back( i-1 );
        }
       
        do{
                for_m op( minput.size()-1,4 );
               
                do{
                        if( is_g_value_print( inx,minput,op.table ) ){
                                count++;
                        }
                }while( op.next() );
               
        }while( std::next_permutation( inx.begin(),inx.end() ) );

        std::cout << "Count = " << count << "  User time: " << GetTickCount() - t0 << std::endl;
        return 0;
}

2

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
 楼主| 发表于 2004-3-1 18:32:00 | 显示全部楼层

Re: 可以加 减 乘 除 算24的程序源!

大家先算算 13,13,3,4,8 吧

程序得用法program 13 13 3 4 8回车

2

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
 楼主| 发表于 2004-3-1 18:35:00 | 显示全部楼层

Re: 可以加 减 乘 除 算24的程序源!

下面是程序的输出
[13/13=1 1+3=4 4*4=16 16+8=24 24]
[13/13=1 1-3=-2 -2+8=6 6*4=24 24]
[13-13=0 0*4=0 0+3=3 3*8=24 24]
[13-13=0 0/4=0 0+3=3 3*8=24 24]
[13-13=0 0*4=0 0+8=8 8*3=24 24]
[13-13=0 0/4=0 0+8=8 8*3=24 24]
[13/13=1 1+8=9 9-3=6 6*4=24 24]
[13+13=26 26-8=18 18/3=6 6*4=24 24]
[13+13=26 26-8=18 18*4=72 72/3=24 24]
[13-4=9 9/3=3 3+13=16 16+8=24 24]
[13-4=9 9/3=3 3+8=11 11+13=24 24]
[13-8=5 5+13=18 18/3=6 6*4=24 24]
[13-8=5 5+13=18 18*4=72 72/3=24 24]
[13+8=21 21/3=7 7+13=20 20+4=24 24]
[13-8=5 5*3=15 15+13=28 28-4=24 24]
[13+8=21 21/3=7 7+4=11 11+13=24 24]
[13-8=5 5*3=15 15-4=11 11+13=24 24]
[13/13=1 1+3=4 4*4=16 16+8=24 24]
[13/13=1 1-3=-2 -2+8=6 6*4=24 24]
[13-13=0 0*4=0 0+3=3 3*8=24 24]
[13-13=0 0/4=0 0+3=3 3*8=24 24]
[13-13=0 0*4=0 0+8=8 8*3=24 24]
[13-13=0 0/4=0 0+8=8 8*3=24 24]
[13/13=1 1+8=9 9-3=6 6*4=24 24]
[13+13=26 26-8=18 18/3=6 6*4=24 24]
[13+13=26 26-8=18 18*4=72 72/3=24 24]
[13-4=9 9/3=3 3+13=16 16+8=24 24]
[13-4=9 9/3=3 3+8=11 11+13=24 24]
[13-8=5 5+13=18 18/3=6 6*4=24 24]
[13-8=5 5+13=18 18*4=72 72/3=24 24]
[13+8=21 21/3=7 7+13=20 20+4=24 24]
[13-8=5 5*3=15 15+13=28 28-4=24 24]
[13+8=21 21/3=7 7+4=11 11+13=24 24]
[13-8=5 5*3=15 15-4=11 11+13=24 24]
[8+13=21 21/3=7 7+13=20 20+4=24 24]
[8+13=21 21/3=7 7+4=11 11+13=24 24]
[8+13=21 21/3=7 7+13=20 20+4=24 24]
[8+13=21 21/3=7 7+4=11 11+13=24 24]
Count = 38  User time: 297

12

主题

82

帖子

93

积分

注册会员

Rank: 2

积分
93
发表于 2004-3-2 11:36:00 | 显示全部楼层

Re:可以加 减 乘 除 算24的程序源!

晕~头都看大了!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-5-14 21:05

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表