蓝桥杯 历届试题 矩阵翻硬币

来源:互联网 发布:mac传照片到安卓手机 编辑:程序博客网 时间:2024/06/05 04:26

蓝桥杯 矩阵翻硬币

n*m的矩阵,按规则翻转,求一开始的正面朝上的个数。
首先,如果一枚硬币被翻了奇数次,那么它原来的状态肯定是反面朝上,所以,我们要找的就是被翻了奇数次的硬币
求哪些数的约束个数有奇数个,完全平方数啊。
那么,ans = (int)sqrt( n ) * (int)sqrt(m) 容易得出。

代码:用了kuangbin的版子。

#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;/** 完全大数模板* 输出cin>>a* 输出a.print();* 注意这个输入不能自动去掉前导0的,可以先读入到char数组,去掉前导0,再用构造函数。*/#define MAXN 9999#define MAXSIZE 1010#define DLEN 4class BigNum{    private:    int a[500]; //可以控制大数的位数    int len;    public:    BigNum(){len=1;memset(a,0,sizeof(a));} //构造函数    BigNum(const int);    //将一个int类型的变量转化成大数    BigNum(const char*); //将一个字符串类型的变量转化为大数    BigNum(const BigNum &); //拷贝构造函数    BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算    friend istream& operator>>(istream&,BigNum&); //重载输入运算符    friend ostream& operator<<(ostream&,BigNum&); //重载输出运算符    BigNum    operator+(const    BigNum &)const;    BigNum    operator-(const    BigNum &)const;    BigNum    operator*(const    BigNum &)const;    BigNum    operator/(const    int &)const;    BigNum operator^(const int &)const;    //大数的n次方运算    int operator%(const int &)const;    //大数对一个int类型的变量进行取模运算    bool operator>(const BigNum &T)const; //大数和另一个大数的大小比较        bool operator>(const int &t)const;        //大数和一个int类型的变量的大小比较        void print();        //输出大数};BigNum::BigNum(const int b) //将一个int类型的变量转化为大数{    int c,d=b;    len=0;    memset(a,0,sizeof(a));    while(d>MAXN)    {    c=d-(d/(MAXN+1))*(MAXN+1);    d=d/(MAXN+1);    a[len++]=c;    }    a[len++]=d;}BigNum::BigNum(const char *s) //将一个字符串类型的变量转化为大数{    int t,k,index,L,i;    memset(a,0,sizeof(a));    L=strlen(s);    len=L/DLEN;    if(L%DLEN)len++;    index=0;    for(i=L-1;i>=0;i-=DLEN)    {    t=0;    k=i-DLEN+1;    if(k<0)k=0;    for(int j=k;j<=i;j++)    t=t*10+s[j]-'0';    a[index++]=t;    }}BigNum::BigNum(const BigNum &T):len(T.len) //拷贝构造函数{    int i;    memset(a,0,sizeof(a));    for(i=0;i<len;i++)    a[i]=T.a[i];}BigNum & BigNum::operator=(const BigNum &n) //重载赋值运算符,大数之间赋值运算{    int i;    len=n.len;    memset(a,0,sizeof(a));    for(i=0;i<len;i++)    a[i]=n.a[i];    return *this;}istream& operator>>(istream &in,BigNum &b){    char ch[MAXSIZE*4];    int i=-1;    in>>ch;    int L=strlen(ch);    int count=0,sum=0;    for(i=L-1;i>=0;)    {    sum=0;    int t=1;    for(int j=0;j<4&&i>=0;j++,i--,t*=10)    {    sum+=(ch[i]-'0')*t;    }    b.a[count]=sum;    count++;    }    b.len=count++;    return in;}ostream& operator<<(ostream& out,BigNum& b) //重载输出运算符{    int i;    cout<<b.a[b.len-1];    for(i=b.len-2;i>=0;i--)    {    printf("%04d",b.a[i]);    }    return out;}BigNum BigNum::operator+(const BigNum &T)const //两个大数之间的相加运算{    BigNum t(*this);    int i,big;    big=T.len>len?T.len:len;    for(i=0;i<big;i++)    {    t.a[i]+=T.a[i];    if(t.a[i]>MAXN)    {    t.a[i+1]++;    t.a[i]-=MAXN+1;    }    }    if(t.a[big]!=0)    t.len=big+1;    else t.len=big;    return t;}BigNum BigNum::operator-(const BigNum &T)const //两个大数之间的相减运算{    int i,j,big;    bool flag;    BigNum t1,t2;    if(*this>T)    {    t1=*this;    t2=T;    flag=0;    }    else    {t1=T;    t2=*this;    flag=1;    }    big=t1.len;    for(i=0;i<big;i++)    {    if(t1.a[i]<t2.a[i])    {    j=i+1;    while(t1.a[j]==0)    j++;    t1.a[j--]--;    while(j>i)    t1.a[j--]+=MAXN;    t1.a[i]+=MAXN+1-t2.a[i];    }    else t1.a[i]-=t2.a[i];    }    t1.len=big;    while(t1.a[len-1]==0 && t1.len>1)    {    t1.len--;    big--;    }    if(flag)    t1.a[big-1]=0-t1.a[big-1];    return t1;}BigNum BigNum::operator*(const BigNum &T)const //两个大数之间的相乘{    BigNum ret;    int i,j,up;    int temp,temp1;    for(i=0;i<len;i++)    {    up=0;    for(j=0;j<T.len;j++)    {    temp=a[i]*T.a[j]+ret.a[i+j]+up;    if(temp>MAXN)    {    temp1=temp-temp/(MAXN+1)*(MAXN+1);    up=temp/(MAXN+1);    ret.a[i+j]=temp1;    }    else    {    up=0;    ret.a[i+j]=temp;    }    }    if(up!=0)    ret.a[i+j]=up;    }    ret.len=i+j;    while(ret.a[ret.len-1]==0 && ret.len>1)ret.len--;    return ret;}BigNum BigNum::operator/(const int &b)const //大数对一个整数进行相除运算{    BigNum ret;    int i,down=0;    for(i=len-1;i>=0;i--)    {    ret.a[i]=(a[i]+down*(MAXN+1))/b;    down=a[i]+down*(MAXN+1)-ret.a[i]*b;    }    ret.len=len;    while(ret.a[ret.len-1]==0 && ret.len>1)    ret.len--;    return ret;}bool BigNum::operator>(const BigNum &T)const//大数和另一个大数的大小比较{    int ln;    if(len>T.len)return true;    else if(len==T.len)    {    ln=len-1;    while(a[ln]==T.a[ln]&&ln>=0)    ln--;    if(ln>=0 && a[ln]>T.a[ln])    return true;    else    return false;    }    else    return false;}bool BigNum::operator>(const int &t)const //大数和一个int类型的变量的大小比较{    BigNum b(t);    return *this>b;}void BigNum::print(){    int i;    printf("%d",a[len-1]);    for(i=len-2;i>=0;i--)    printf("%04d",a[i]);    printf("\n");}BigNum l,r,mid,n,m;int main(){    cin>>n>>m;    BigNum N=1,M=1;    l=1;r=n;    while(!(l>r)){    mid=(l+r)/2;    if(!(mid*mid>n)){        N=mid;        l=mid+1;    }    else r=mid-1;    }    l=1;r=m;    while(!(l>r)){    mid=(l+r)/2;    if(!(mid*mid>m)){        M=mid;        l=mid+1;    }    else r=mid-1;    }    BigNum ans=N*M;    ans.print();    return 0;}
0 0
原创粉丝点击