2014华为校招 重邮机试 2013.9.15 第三场

本文介绍了一种使用3进制数进行状态遍历的算法实现,通过一个具体的编程问题展示了解决方案。该算法利用3进制数的不同状态来表示表达式中的空白、加号和减号,从而遍历所有可能的组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来源:http://download.youkuaiyun.com/detail/zhou20071801/6276543

 

第一题:

 

 

第二题:

 

 

第三题:

 

 

总结:第一、二题比较水,第三题对3^8=6561种状态如何方便的遍历是个问题,联想到以前做的一道题http://blog.youkuaiyun.com/hntyzhangpeng/article/details/38421859 里用0/1二进制数表示两种状态,使用一个数来遍历所有可能的状态。这里采用了类似的方法,只是换成了3进制数,数用一个数组表示,编写状态变化函数,每次递增1,每个位3个状态,即3进制数:0-空白(连接符),1-加号,2-减号这样可以确保所有的状态都遍历到。

与此算法类似的其他人的一个解如下链接:http://blog.youkuaiyun.com/KeepThinking_/article/details/8521975

以下附上个人的代码,自觉写的还比较简洁:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<list>
#include<stack>
#include<queue>
#include<string>
#include<algorithm>

using namespace std;

char flag[8]={0}; //8 slots;  0 --no   1--'+'  2--'-'
//状态变化函数,每次递增1,每个位3个状态,即3进制数:0-空白(连接符),1-加号,2-减号
//遍历满时返回-1,其他情况返回0
//共 3^8(3的8次方)= 6561 种状态
int  next(){
    int num = 0;
    int  carry = 0;
    //每次递增1,每个位3个状态,即3进制数
    flag[0]++;
    for(int i=0;i<=7;i++){      
        if(flag[i]>2){
            if(i==7)
                return -1;  //计算满
            flag[i] = 0;
            flag[i+1]++;
        }
        else 
            break;
    }
    return 0;
}
//1_2_3_4_5_6_7_8_9   其中'_'处可以有三种状态,0 空白(连接符),1 加号 ,2 减号
int main(){

#ifndef ONLINE_JUDGE
    //freopen("testCase.txt","r",stdin);
#endif
    int sum =0;
    int cnt=0;
    int operand = 0;
    int expectValue = 0;
    char operation = 0;
    while(scanf("%d",&expectValue)!=EOF){
        //初始化
        cnt  = 0;
        for(int i=0;i<8;i++)
            flag[i] = 0;
        //遍历所有状态
        do{
            sum = 0;
            operand  = 1;
            operation = '+';
            for(int i=2;i<=10;i++){
                if(i==10){
                   sum += (operation =='+')? operand:-operand;
                    break;
                }
                if(flag[i-2]==0)  //连接符
                    operand  = 10*operand + i;
                else if(flag[i-2]==1||flag[i-2]==2){// + -
                    sum += (operation =='+')? operand:-operand;
                    operand = i;
                    if(flag[i-2]==1)
                        operation = '+';
                    else
                        operation = '-';
                }
            }
            if(sum ==expectValue)
                cnt++;
        }while(!next());
        printf("%d\n",cnt);
    }
    //fclose(stdin);
    return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值