zoukankan      html  css  js  c++  java
  • 蓝桥杯 矩阵翻硬币

    蓝桥杯 矩阵翻硬币

    暴力

    • 暴力模拟: 但是发现暴力模拟只能通过第一个样例,因为数的范围太大了,所以说是思路上的问题

    考虑整个过程

    我参考了h_hui_hui大佬的博客,他写的很详细,很容易看懂

    感觉那样一步一步推导出结果的过程很酷,也很难

    现在能看懂,但是如果自己想的话就可能出问题,积累经验吧

    具体分析请看博客

    结论

    ans = sqrt(n) * sqrt(m) # 两个都是向下取整

    所以会用到大数相乘, 大数开根号

    还有一个结论:

    假设位数为len的整数,开方取整后为一个lenSqrt位数
    
    当len为偶数,lenSqrt = len / 2
    当len为奇数,lenSqrt = (len / 2) + 1
    

    其中大数相加可以通过我的上一篇博客了解

    比较佩服大佬的一点就是开根号那个操作,实在是厉害

    code

    #include <bits/stdc++.h>
    
    //find a solution : cnt = sqrt(m) * sqrt(n) and ji * ji = ji
    //大数相乘,大数开根号
     
    using namespace std;
    
    string strMultiply(string str1,string str2){
    	string strResult = "";
    	int len1 = str1.length();
    	int len2 = str2.length();
    	int num[500] = {0};
    	int i = 0 , j = 0 ;
    	for(i = 0; i <len1; i++){
    		for(j = 0;j < len2; j++){
    			num[len1-1-i+len2-1-j] += (str1[i]-'0') * (str2[j]-'0');//这里当时写错了不是两个 i str1[i] str2[j] 
    		}
    	}
    	for(i = 0 ; i < len1+len2; i++){
    		if(num[i] >= 10){
    			num[i+1] += num[i]/10;
    			num[i] %= 10; 
    		}
    	}
    	for(i = len1+len2-1; i>= 0; i--){
    		if(num[i] != 0)break;	
    	}
    	
    	for(j = i ; j >= 0; j--){
    		strResult += num[j] + '0';
    	}
    	return strResult;	
    } 
    
    //添加 pos 个 0 然后在做比较 
    int compare(string str1,string str2,int pos){
    	int len1 = str1.length();
    	int len2 = str2.length();
    	if(len2 > len1 + pos)return 0;
    	if(len2 < len1 + pos)return 1;
    	int i = 0;
    	for(i = 0; i < len2; i++){
    		if(str1[i]-'0'>str2[i]-'0')return 1;
    		if(str1[i]-'0'<str2[i]-'0')return 0;
    	}
    	return 0;
    }
    // 如果数比较大的话,可能会出现不该出现的 比如 : /
     
    string sqrtLarge(string str){
    	int len = str.length();
    	int i = 0, j = 0;
    	string strResult = "";
    	string str1 = "";
    	
    	if(0 == len % 2)  
        {         //为偶数位  
            for(i = 0; i < len/2; i++)
            {  
                for(j = 0; j < 10; j++)  
                {  
                    str1 = strResult;  
                    str1 += j + '0';  
                    if(1 == compare(strMultiply(str1, str1) , str , 2*(len/2-i-1)) )  
                    {         //由于str1后少了len/2-i-1个0,所以平方以后少了2*(len/2-i-1)个  
                        strResult +=  j-1 + '0';
                        break;  
                    }  
                    if(9 == j) strResult += '9';  
                }  
            }  
        }
        else  
        {       //为奇数位  
            for(i = 0; i < len/2+1; i++)  
            {  
                for(j = 0; j < 10; j++)  
                {  
                    str1 = strResult;  
                    str1 += j + '0';  
                    if(1 == compare(strMultiply(str1, str1) , str , 2*(len/2-i)) )  
                    {  
                        strResult +=  j-1 + '0';
                        break;  
                    }  
                    if(9 == j) strResult += '9';  
                }  
            }  
        }  
        return strResult;  
    }
    
    int main(){
    	string str1;
    	string str2;
    //	string strResult;
    	cin >> str1 >> str2;
    	cout << strMultiply(sqrtLarge(str1),sqrtLarge(str2)) << endl;
    		
    	return 0;
    } 
    //test
    //979 938
    //930
    

    总结

    如果是自己的话,推导,实现,这两个都成问题,
    特别是开根号那个操作,看了很长时间,加油吧,累计做题经验吧
  • 相关阅读:
    训练赛(28)—— 计蒜客 45724 Jumping Frog
    训练赛(28)—— 计蒜客 45725 Fujiyama Thursday
    centos上libreoffice+unoconv安装步骤,实现word转pdf
    PhantomJS linux系统下安装步骤及使用方法(网页截屏功能)
    knockout应用开发指南(完整版)
    git 创建版本库
    保留json字符串中文的函数,代替json_encode
    微信公众平台开发接口PHP SDK完整版(转载)
    find_in_set()
    NuSOAP与PHPRPC比较(转)
  • 原文地址:https://www.cnblogs.com/pprp/p/8666324.html
Copyright © 2011-2022 走看看