//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");
}