IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 第十二届蓝桥杯省赛大学B组 试题D货物摆放 -> 正文阅读

[C++知识库]第十二届蓝桥杯省赛大学B组 试题D货物摆放

试题题目

在这里插入图片描述
本题答案:2430
解题思路:

  1. 第一次编写程序:
    ?? 题目给出的 n n n数值为 16 16 16位数字, C C C语言中有类型 l o n g long long? l o n g long long? i n t int int,其范围为 ? 9223372036854775808 -9223372036854775808 ?9223372036854775808~ 9223372036854775807 9223372036854775807 9223372036854775807,为 19 19 19位数值完全可以存储 n n n;观察题目给出的例知:不需要进行去重处理。即虽因数相同,但所在位置不同,属于两种不同的方案。编写一个程序计算 n n n的所有因数,发现因数个数为 128 128 128个,可以简单地使用暴力的方法(三重循环),当符合 “ n = “n= n=因数1 ? * ?因数2 ? * ?因数3 ” ” 式子时,统计变量 s u m sum sum加一。代码如下:
#include<stdio.h>
#include<math.h>
#define n 2021041820210418 
long long int inshu[1000];
int sum = 0;
int main(){
	long long int geshu;
	int i,j,z;
	geshu = factor(n);
	for(i=0;i<geshu;i++){
		for(j=0;j<geshu;j++){
			for(z=0;z<geshu;z++){
				if(inshu[i] * inshu[j] *inshu[z] == n){
					sum++; 
					//printf("%lld * %lld *%lld = %lld  %lld \n",inshu[i],inshu[j],inshu[z],n,sum);//检测代码 
				}
			}
		}
	}
	printf("%d\n",sum);
	return 0;
}

int factor(long long int N){  //寻找N的所有因数的函数; 
	long long int i,k;
	k = 0;
	for(i=1; i<=sqrt(N); i++){  //这里找寻找到了一半的因数 
		if(N%i ==  0){
			inshu[k++] = i;
		}	
	}
	if(sqrt(N) == inshu[k-1]){ i = k-1; }   //当这个数是某个数的平方项时需要在因数中减去一个数,避免因数重复
	else{ i = k; }
	while(--i >= 0){           //把另一半的因数补齐 
		inshu[k++] = N / inshu[i];
	}
	return k;
}
  1. 第二次编写程序(第一次优化):
    ??暴力求解的方法,其时间复杂度为 O ( n 3 ) O(n^3) O(n3),造成了时间上的消耗,对上一个算法进行优化,优化方法为:通过调用 f a c t o r ( ) factor() factor() 函数,找出n的所有因数,把 n n n拆分为 “ n = “n= n=因数1 ? * ?因数2 ? * ?因数3 ” ” 的式子;在对因数2调用 f a c t o r ( ) factor() factor()找出因数2的所有因数,把因数2拆分为 “ “ 因数2 = = =因数21 ? * ?因数22 ” ” 的式子;把这两个式子合并,便可以得出 “ n = “n= n=因数1 ? * ?因数2 ? * ?因数3 ” ” ”,统计式子的个数,便可以得出答案。代码:
#include<stdio.h>
#include<math.h>
#define n 2021041820210418 
int sum = 0;      //统计式子个数的变量 
long long int *factor(long long int N,long long int inshu[1000]);
int main(){
	long long int yinshu[1000] = {0}; //存储n的所有的因数; 
	int i,j;
	factor(n,yinshu);
	for(i=0; i<yinshu[999]; i++){
		long long int zinshu[1000] = {0}; //存储所有因数的因数数组
		factor(n/yinshu[i],zinshu);
		for(j=0;j<zinshu[999]; j++){
			sum++;
			//printf("%lld * %lld * %lld = %lld  %d \n",yinshu[i],zinshu[j],n/yinshu[i]/zinshu[j],n,sum); //检测代码 
		}
	} 
	printf("%d\n",sum);
	return 0;
}

long long int *factor(long long int N,long long int inshu[1000]){
	long long int i,k;
	k = 0;
	for(i=1;i<=sqrt(N);i++){  //这里找寻找到了一半的因素 
		if(N%i == 0){
			inshu[k++] = i;
		}	
	}
	if(sqrt(N) == inshu[k-1]){ i = k-1; }   //当这个数是某个数的平方项时需要在因数中减去一个数 
	else{ i = k; }
	while(--i >= 0){   //把另一半的因数补齐 
		inshu[k++] = N / inshu[i];
	}
	inshu[999] = k;   //计算之前跑一下程序发现n因数不超过900个,可知k就是N的因子个数,并把它储存与inshu数组的最后一个值,目的为了传回到主函数中。 
	return inshu;
}
  1. 第三次编写程序(第二次优化)
    ??通过深度分析,比较上述两个算法,可以对以上算法进一步简化。
    ??优化过程:因不需要去重,假设 f 1 ? f 2 ? f 3 = n f1 * f2 * f3 = n f1?f2?f3=n ,根据这一个式子直接可以得出另外五个式子:“ f 1 ? f 3 ? f 2 = n f1 * f3 * f2 = n f1?f3?f2=n ”、“ f 2 ? f 1 ? f 3 = n f2 * f1 * f3 = n f2?f1?f3=n”、“ f 2 ? f 3 ? f 1 = n f2 * f3 * f1 = n f2?f3?f1=n”、“ f 3 ? f 1 ? f 2 = n f3 * f1 * f2 = n f3?f1?f2=n” 以及 “ f 3 ? f 2 ? f 1 = n f3 * f2 * f1 = n f3?f2?f1=n”。
    ??注意
    ??(1)当 f 1 = f 2 = f 3 f1 =f2 = f3 f1=f2=f3时, f 1 ? f 2 ? f 3 = n f1 * f2 *f3 = n f1?f2?f3=n 只能算作一个式子;
    ??(2)当 f 1 = f 2 f1 = f2 f1=f2 或者 f 1 = f 3 f1=f3 f1=f3 或者 f 2 = f 3 f2=f3 f2=f3时, f 1 ? f 2 ? f 3 = n f1 * f2 * f3 = n f1?f2?f3=n 改变位置后共得出三个式子;
    ??(3)当 f 1 ≠ f 2 ≠ f 3 f1 \neq f2 \neq f3 f1?=f2?=f3时, f 1 ? f 2 ? f 3 = n f1 * f2 * f3 = n f1?f2?f3=n ,可以算作六个不同式子;
    ??(4)为了避免重复计算,需要保证 f 1 ≤ f 2 ≤ f 3 f1 \le f2 \le f3 f1f2f3
    ??以上两个算法,都使用了函数和数组,求因数再储存因数,消耗大量的存储空间。而求因数的过程特别简单,就是拿这个数( n n n)除以小于它的数值( i i i),如果能够被整除( n ? m o d ? i = 0 n \bmod i = 0 nmodi=0),那么 i i i就是它的第一个因数, n / i n/i n/i就是它的第二个因数( j j j)。用一个循环即可实现,循环条件设置为( i ≤ s q r t ( n ) i \le sqrt(n) isqrt(n)),保证了第一个因数小于第二个因数;再对第二个因数使用同样的循环,寻找出第二个因数的因数。第三个因数就是 n / i / j n/i/j n/i/j.
    具体代码:
#include<stdio.h>
#include<math.h>
#define n 2021041820210418 
int main(){
	long long int i,j;
	int sum = 0;      //统计式子个数的变量 
	for(i=1;i<=sqrt(n);i++){
		if(n%i == 0){  //i是n的第一个因数 
			for(j=i;j<=sqrt(n/i);j++){ //j从i开始循环,保证了i<=j 
				if(n/i%j == 0){  //j是n的第二个因数 
					if(i==j && j==n/i/j){sum++;}
					else if(i==j || j==n/i/j || i==n/i/j){sum+=3;}
					else {sum+=6;}
					//printf("%lld  %lld %lld %d \n",i,j,n/i/j,sum); //检测代码
				}	
			}
		}
	}
	printf("%d",sum);
} 
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-26 12:02:17  更:2021-10-26 12:04:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:19:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码