矩阵翻硬币
一道蓝桥杯的题目,说实话如果没有推出来这个结论,感觉挺难写的
结论的证明,我可以大概说一下,可以先模拟小的样例,观察出规律,发现奇数次翻转才会产生真正的变化,(具体证明以后补充)
这里先给出结论:
结论就是sqrt(n)+sqrt(m);
code:
#include <iostream> #include <map> #include <vector> using namespace std; string mul(string a,string b){ int n=a.size(); int m=b.size(); string res=""; vector<int> c(n+m+10); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ c[n-i-1+m-j-1]+=((a[i]-'0')*(b[j]-'0')); } } for(int i=0;i<c.size();i++){ c[i+1]+=c[i]/10; c[i]%=10; } int i=c.size()-1; while(c[i]==0&&i>0)i--; for(;i>=0;i--){ res+=(char)(c[i]+'0'); } return res; } bool compare(string s1,string s2,int p){ int n=s1.size(); int m=s2.size(); if(n+p>m)return true; if(n+p<m)return false; for(int i=0;i<n;i++){ if(s1[i]-'0'>s2[i]-'0'){ return true; } if(s1[i]-'0'<s2[i]-'0'){ return false; } } return false; } /* 大数开方的一个结论,先记录一下。 假设位数为len的整数,开方取整后为一个lenSqrt位数。 当len为偶数,lenSqrt = len / 2 . 当len为奇数,lenSqrt = (len / 2) + 1 . */ string m_sqrt(string s){ int n=s.size(); string res=""; if(n%2==0){ for(int i=1;i<=n/2;i++){ int j=0; for(j=0;j<10;j++){ if(compare(mul(res+(char)(j+'0'),res+(char)(j+'0')),s,2*(n/2-i))){ res+=(char)(j-1+'0'); break; } if(j==9)res+='9'; } } } else{ for(int i=1;i<=n/2+1;i++){ int j=0; for(j=0;j<10;j++){ string tem=res+(char)(j+'0'); if(compare(mul(tem,tem),s,2*(n/2+1-i))){ res+=(char)(j-1+'0'); break; } if(j==9)res+='9'; } } } return res; } int main(){ string n,m; cin>>n>>m; // 结论就是sqrt(n)+sqrt(m); cout<<mul(m_sqrt(n),m_sqrt(m))<<endl; }

浙公网安备 33010602011771号