实现高精度的加法、减法、快速除法。
- #include<iostream>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- using namespace std;
-
- class Bign{
- public:
- Bign(){};
- Bign(string a);
- void add(const Bign& a); //加法
- void minus(const Bign& a); //减法
- Bign devide(const Bign& a); //除法,返回商,自己变成余数
- friend ostream& operator<<(ostream &out,const Bign &obj);
- int compare(const Bign& a);
- private:
- string data;//低位在前,高位在后
-
- };
-
- int main(){
-
- string a,b;cin>>a>>b;
- Bign A(a),B(b);
- cout<<A.devide(B)<<endl;
- cout<<A;
-
- return 0;
- }
-
- Bign Bign::devide(const Bign& a){
- Bign ans("0");
- Bign copy_a=a;
-
- int Len=a.data.size();
- int t=data.size()-Len-1;
- //每次减一个大的数
- while(t>0){
- copy_a.data.insert(0,string(t,'0'));
- Bign W("1");
- W.data.insert(0,string(t,'0'));
- while(compare(copy_a)==1){
- minus(copy_a);
- ans.add(W);
- }
- copy_a=a;
- t=data.size()-Len-1;
- }
- //减法 (直接做减法会超时)
- while(compare(copy_a)>=0){
- minus(copy_a);
- ans.add(Bign("1"));
- }
- return ans;
- }
-
-
- void Bign::minus(const Bign& a){
- int newLen=data.size();
- string ans(newLen,'0');
- int temp=0;
- for(int i=0;i<newLen;i++){
- temp+=(data[i]-'0');
- if(i<a.data.size())temp-=(a.data[i]-'0');
- if(temp<0){
- ans[i]+=temp+10;
- temp=-1;
- }else{
- ans[i]+=temp;
- temp=0;
- }
- }
- for(temp=newLen-1;ans[temp]=='0';temp--);
- ans.erase(temp+1);
- this->data=ans;
- }
-
- int Bign::compare(const Bign& a){
- if(this->data.size()>a.data.size())return 1;
- if(this->data.size()<a.data.size())return -1;
- for(int i=data.size()-1;i>=0;i--){
- if(data[i]>a.data[i])return 1;
- if(data[i]<a.data[i])return -1;
- }
- return 0;
- }
- void Bign::add(const Bign& a){
- int newLen=max(data.size(),a.data.size())+1;
- string rel(newLen,'0');
- int temp=0;
- for(int i=0;i<newLen ;i++){
- if(i<data.size())temp+=data[i]-'0';
- if(i<a.data.size())temp+=a.data[i]-'0';
- rel[i]+=temp%10;
- temp/=10;
- }
- if(rel[newLen-1]=='0')rel.erase(newLen-1);
- this->data=rel;
- }
- ostream& operator<<(ostream &out,const Bign &obj){
- if(obj.data.empty()){
- cout<<'0';
- }else{
- for(int i=obj.data.size()-1;i>=0;i--)
- out<<obj.data[i];
- }
- return out;
- }
- Bign::Bign(string a){
- reverse(a.begin(),a.end()) ;
- data=a;
- }
-
给出一个整数 n(n< 10^30) 和 k 个变换规则(k< =15)。
规则:
一位数可变换成另一个一位数:
规则的右部不能为零。
例如:n=234。有规则(k=2):
2-> 5
3-> 6
上面的整数 234 经过变换后可能产生出的整数为(包括原数):
234、534、264、564
共 4 种不同的产生数
问题:
给出一个整数 n 和 k 个规则。
求出:经过任意次的变换(0次或多次),能产生出多少个不同整数。
仅要求输出个数。
234 2
2 5
3 6
4
- (a) 先用Floyd算法,求出某一个数字可以到达的目的地(即经过0次或若干次变换的结果)
- (b) 高精度运算
- 但是int(4字节)的范围是[-2^31^,2^31^-1],即[-2147483648,2147483647],
- 用一个int来表示1个数字太浪费了,可以用1个int来存储8位数(为了使得乘法不越界),
-
- #include<iostream>
- #include<vector>
- #include<string>
- #define INF 99999
- using namespace std;
-
- class bign{
- public:
- bign(int k=0){data.push_back(k);}
- vector<int> data;
- void mult(int k);
- friend ostream& operator<<(ostream &out, bign& obj);
- static int N;
- };
- int bign::N=10000000;
-
-
-
- void bign::mult(int k){
- if (k==1)return;
- int L=data.size();
- int t=0;
- for(int i=0;i<L;i++){
- data[i]=data[i]*k+t;
- t=data[i]/N;
- data[i]%=N;
- }
- if(t)
- data.push_back(t);
- }
- ostream& operator<<(ostream &out,bign& obj){
- int t=obj.data.size()-1;
- out<<obj.data[t--];
- for(int i=t;i>=0;i--){
- //out<<'-';
- for(int k=0;k<7-NumOfDig(obj.data[i]);k++)
- out<<'0';
- out<<obj.data[i];
- }
- return out;
- }
-
- int NumOfDig(int k){//判断数字位数
- if(k==0)return 1;
- int rel=0;
- while(k>0){
- k/=10;
- rel++;
- }
- return rel;
- }
- int main(){
- string n;cin>>n;
- int k;cin>>k;
- int d[10][10];//Floyd算法距离
- //初始化
- for(int i=0;i<10;i++)
- for(int j=0;j<10;j++)
- d[i][j]=INF;
-
-
- int x,y;
- for(int i=0;i<k;i++){
- cin>>x>>y;d[x][y]=1;
- }
- //Flody算法的三重循环
- for(int k=0;k<10;k++)
- for(int i=0;i<10;i++)
- for(int j=0;j<10;j++)
- if(d[i][j]>d[i][k]+d[k][j])
- d[i][j]=d[i][k]+d[k][j];
- int flag[10]={0};//用于记录该数字会变成几种其他数字
- for(int i=0;i<10;i++){
- d[i][i]=1;//确保可以到达自己(即可以通过0次变换)
- for(int j=0;j<10;j++)
- if(d[i][j]<INF)
- flag[i]++;
- }
-
- if(0){//测试代码
- for(int i=0;i<10;i++){
- for(int j=0;j<10;j++){
- cout<<d[i][j]<<' ';
- }cout<<endl;
- }
- cout<<"*******************"<<endl;
- for(int i=0;i<10;i++)
- cout<<flag[i]<<' ';cout<<endl;
- cout<<"*******************"<<endl;
- }
- bign rel(1);
- for(int i=0;i<n.length();i++)
- rel.mult(flag[n[i]-'0']);
-
- cout<<rel;
- return 0;
- }
-
-