编程之美2.8查找符合条件的数

 
//N*M,N给定值,求最小M使得N*M的值中只有0或1
#include<iostream>
#include<stdio.h>
#include<bitset>
using namespace std;   
int head_0(unsigned long b){//b的32位二进制表示前面有多少个0
    int count=0;
    unsigned long tp=0x80000000;
    while(!(b&tp)){count++;b<<=1;}
    return count;
}    
int tail_0(unsigned long b){//b的32位的二进制表示后面有多少个0
    int count=0;
    while(!(b&1)){count++;b>>=1;}
    return count;
}    
unsigned long val(unsigned long b){//把b的二进制转成十进制,如 二进制0010 转成 十进制10
    unsigned long tp=0x80000000;
    int tail=tail_0(b);
    int head=head_0(b);
    b<<=head;
    unsigned long sum=0;
    while(b){
        sum+=((b&tp)>>31);sum*=10;
        b<<=1;
    }   sum/=10; 
    for(int i=0;i<tail;i++)sum*=10;
    return sum;
}    
bool is_2_power(unsigned long i){//b所对应的二进制是不是2的整数次幂,也是b二进制所对应的10进制是不是10的整数次幂
    return !(i&(i-1));
}    
class mod{//存储mod N的1到N-1的剩余类的最小值
    int * a;
    int N;
    int full;
public:
    mod(int n):N(n){
        a=new int[N];full=0;
        for(int i=0;i<N;i++)a[i]=-1;
    }
    void set(int i,int j){
        if(a[i]==-1){a[i]=j;full++;}
    }
    int get(int i){return a[i];}
    bool is_full(){return full==N-1;}
    void display(){
        for(int i=1;i<N;i++){
            cout<<val(a[i])<<" "<<val(a[i])%N<<endl;
        }    
    }    
};
unsigned long _10_power(int i){//10的i次方
    unsigned long sum=1;
    for(int j=0;j<i;j++)sum*=10;
    return sum;
}    
int main(){//unsigned long 4B
    unsigned long i=1;//0000 0000 0000 0000 0000 0000 0000 0001    
    cout<<"input N\n";   
    int N;cin>>N;
    mod m(N);
    while(!is_2_power(i) || !m.is_full()){//当剩余类未满 或 val(i)不是10的倍数 ,一直运算 
        int modd=val(i)%N;
        if(modd==0){cout<<"找到符合条件的M:"<<val(i)/N<<endl<<"乘积为"<<val(i)<<endl;system("pause");m.display();system("pause");return 0;}
        m.set(modd,i);
        i++;
    }    
    cout<<"已运算到"<<val(i)<<"仍未发现满足条件的值,\n但我已经生成N的所有剩余类\n接下来我开始拼接,对应的K位数只运算N-1次\n展示剩余类"<<endl;
    
    m.display();cout<<endl;
    
    int a=tail_0(i);
    
    unsigned long res;
    
    for(unsigned long k=_10_power(a);;k*=10){
        for(int j=1;j<N;j++){
            res=k+val(m.get(j));
            if(res%N==0){cout<<"找到符合条件的M:"<<res/N<<endl<<"乘积为"<<res<<endl;system("pause");return 0;}
        }    
    }    
    
    system("pause");
}    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值