算法很美——数学问题
算法很美——数学问题
- 题1:天平称重
问题描述:
用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
砝码重量分别是1,3,9,27,81……3的指数次幂,每种重量砝码只有一个
则它们可以组合称出任意整数重量(砝码允许放在左右两个盘中)。
本题目要求编程实现:对用户给定的重量,给出砝码组合方案。
例如:
用户输入:
5
程序输出:
9-3-1
用户输入:
19
程序输出:
27-9+1
要求程序输出的组合总是大数在前小数在后。
可以假设用户的输入的数字符合范围1~1000000
思路:3的指数次幂——可以想到用3进制,将输入转为三进制,按位输出,而二进制中可能出现2,但同一重量砝码只有一个,考虑加一减一,如下
19的三进制表示:
2 0 1:二位加一变成:1 0 0 1
减一变成:1 -1 0 1
这样可以使三进制表示中只有1,0,-1
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int k[10],num;
void fun(int a)
{num=0;int flag=0;while(a){if(a%3==2){k[num++]=-1;a/=3;a++;}else {k[num++]=a%3;a/=3;}}//printf("num=%d\n",num);//for(int i=num-1;i>=0;i--)printf("%d ",k[i]);printf("\n");for(int i=num-1;i>=0;i--){//printf("i+1=%d pow=%d\n",i+1,pow(3,i+1));if(k[i]<0)printf("-%d",(int)pow(3,i));else if(k[i]==1){if(flag)printf("+%d",(int)pow(3,i));else printf("%d",(int)pow(3,i));}flag=1;}printf("\n");
}
int main()
{int n;while(scanf("%d",&n)!=-1)fun(n);return 0;
}
- 题2:Nim游戏
Nim游戏特点:
n个部分,任意取,至少一个,轮流,取光为赢,两人均为最优策略
思路:
所有堆进行异或
如果结果为0,则任何取法都将使之变成非零
如果结果不是零,则总有取法使之变成零
所以结果为零,先手输;结果非零,先手赢。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void fun(int a[],int n)
{int t=a[0];for(int i=1;i<n;i++)t^=a[i];if(t){printf("WIN:1\n");return;}else{printf("WIN:2\n");return;}
}
int main()
{int n;while(scanf("%d",&n)!=-1){int a[n];for(int i=0;i<n;i++)scanf("%d",&a[i]);fun(a,n);}return 0;
}
- 题3:Georgia ans Bob——Nim的变形
题目描述:
Georgia和Bob在玩游戏。一个无限长的棋盘上有N个旗子,第i个棋子的位置可以用Pi表示。现在Georgia先走。每个人每一次可以把一枚棋子向左移动任意个格子,但是不能超越其他棋子,也不能和其他棋子处在同一个格子里。如果轮到某一个人的时候Ta再也不能移动棋子了,就判负。现在每个测试数据给定一种情况,如果Georgia会赢,输出“Georgia will win”,如果Bob会赢,输出“Bob will win”
思路:
“直到不能移动——间隔为0”,“可以向左移动任意格,不能跨越,至少移动1格”
可以考虑用Nim问题思路解决
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void Nim(int a[],int n)
{int res=a[0];for(int i=1;i<n;i++)res^=a[i];if(res){printf("WIN:1\n");return;}else printf("WIN:2");
}
void fun(int a[],int n)
{int b[n/2+1],j=0;if(n%2==0){for(int i=1;i<n;i+=2)b[j++]=a[i]-a[i-1]-1;}else{for(int i=0;i<n;i+=2)b[j++]=i==0?a[0]:a[i]-a[i-1]-1;}Nim(b,j);
}
int main()
{int n;while(scanf("%d",&n)!=-1){int a[n];for(int i=0;i<n;i++)scanf("%d",&a[i]);sort(a,n);fun(a,n);}return 0;
}
- 重要求和公式
等差:
平方和、立方和:
等比:
调和级数:=lnn
- gcd
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int gcd(int m,int n)
{return n==0?m:gcd(n,m%n);
}
int main()
{int a,b;while(scanf("%d %d",&a,&b)!=-1)printf("%d\n",gcd(a,b));return 0;
}
- 题3:
在两点间线段上,有几个点横纵坐标均为整数
gcd(d1,d2)-1个 - 裴蜀公式(贝祖公式)
- 素数筛——求第N个素数
求第N个素数的普通算法(看从2到根号N是否有数能将N除尽)——O(N根号N)
为提高效率可使用埃氏筛,依次筛掉2,3,4,5······的倍数,得到一个素数表——O(nlognlogn)
思路:先开空间(数组),再筛倍数
开空间大小?
有素数定理可得,在X范围内,大致有X/logX个素数
例题:求第100002个素数
#include <iostream>
#include <bits/stdc++.h>
#define N 100002
using namespace std;
void fun()
{long n=2,i=2;while(n/log(n)<N)n++;n+=5;printf("n=%ld\n",n);int arr[n];memset(arr,0,sizeof(arr));while(i<n){if(arr[i]!=0){i++;continue;}int k=2;while(i*k<n){arr[i*k]=-1;k++;}i++;}long num=0;for(int j=2;j<n;j++){if(arr[j]==0)num++;if(num==N){printf("%d\n",j);return;}}printf("num=%ld\n",num);
}
int main()
{fun();return 0;
}
100002超时
- 快速幂——求n的m次幂
求n的平方的平方的平方···直到大于所求,剩下的幂次递归
#include <iostream>
#include <bits/stdc++.h>
#define N 100002
using namespace std;
int fun(int n,int m)
{if(m==1)return n;if(m==0)return 1;int ans=n,i=1;while(i*2<=m){ans*=ans;i*=2;}return ans*fun(n,m-i);
}
int main()
{int n,m;while(scanf("%d %d",&n,&m)!=-1)printf("%d\n",fun(n,m));return 0;
}
- 快速幂方法二:巧算
例:a的10次方
10:(1010)2
所以,a的10次方等于a的2的3次方*a的2的1次方
#include <iostream>
#include <bits/stdc++.h>
int fun(int m,int n)
{int result=1,pingfangshu=m;if(n==0)return 1;while(n){if((n&1)==1)result*=pingfangshu;pingfangshu*=pingfangshu;n>>=1;}return result;
}
int main()
{int m,n;while(scanf("%d %d",&m,&n)!=-1)printf("%d\n",fun(m,n));return 0;
}
- 斐波那契数列的另一种求法——类似于幂运算
算法很美——数学问题相关推荐
- 算法很美-位运算-找出落单的那个数
上级目录:算法很美 1. 题目 一个数组里除了某一个数字之外,其他的数字都出现了两次.请写程序找出这个只出现一次的数字. 2. 异或思路 异或的运算是A ^ A=0,也就是说偶数个相同的元素异或,结果 ...
- <<算法很美>>——(七)——DFS典题(二):数独游戏
目录 问题描述 问题分析 放码过来: 问题描述 如[图1.png],玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一 行.每一列.每一个同色九宫内的数字均含1-9,不重复. 数 ...
- <<算法很美>>——(三)十大排序算法(上)
目录 前言 冒泡排序 图解冒泡 代码实现 冒泡优化 选择排序 图解选排 代码实现 插入排序 图解插入 代码实现 希尔排序 图解希尔 代码实现: 归并排序 图解归并 代码实现 快速排序 图解快排 ...
- <<算法很美>>——(三)十大排序算法(下)
目录 1. 奇数在左偶数在右 2. 最快效率求出乱序数组中第k小的数 3. 数组中有一个数字出现次数超过数组长度一半 4. 合并两个有序数组 5. 数组中的逆序对 6. 排序数组中两个数字之和 7. ...
- 蓝桥杯:算法很美 笔记 3.查找和排序(Python实现)
1.分治法介绍以及关键点解析 分治法(divide and conquer, D&C)∶将原问题划分成若干个规模较小而结构与原问题一致的子问题﹔递归地解决这些子问题,然后再合并其结果,就得到原 ...
- <<算法很美>>——(七)——DFS典题(一):水洼数目
目录 问题描述 问题分析 放码过来 问题描述 有一个大小为N×MN×M N\times MN×M的园子,雨后积起了水.八连通的积水被认为是连接在一起的.请求出园子里总共有多少水洼?八连通指的是下图中相 ...
- <<算法很美>>——(四)——深入递归<一>——自上而下,自下而上
目录 前言 上楼梯 机器人走方格 前言 接着上篇博客详解递归思想我们继续更深入地分析递归,本篇主要更加深入讲解上篇的自下而上和自上而下思想. 啥叫「自顶向下」?是从上向下延伸,都是从一个规模较大的原问 ...
- 算法很美 笔记 4.多维数组与矩阵
4.多维数组与矩阵 题1 :顺时针打印二维数组 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] ...
- 蓝桥杯算法很美笔记—排序实现题
题1:小白上楼梯(递归设计) 小白正在上楼梯,楼梯有n阶台阶,小白一次可以上1阶,2阶或者3阶,实现一个方法,计算小白有多少种走完楼梯的方式. 思路: 一次可以上1阶,2阶或者3阶,则最后一步可以为上 ...
最新文章
- 企业级监控ZABBIX深度实践安装部分
- 关于 sql server 基本使用的建议
- LeetCode之 insertion-sort-list insertion-sort-list
- Value 'EN' violates facet information 'maxlength=1'
- [SDOI2008]SUE的小球
- 没人性!让我们这么早来上班
- 第四届 AI City 挑战赛 @ CVPR 2020 开始啦!
- 3009基于二叉链表的二叉树结点个数的统计(附思路)
- python发QQ邮件
- VMWARE下安装Linux系统 CentOS-7-x86
- 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_09-webpack研究-webpack介绍
- 【树叶识别】基于matlab PNN神经网络树叶类别【含Matlab源码 798期】
- mysql truncate 日期_(LINQ to Entities)使用日期判断条件Truncate日期函数
- java从本地下载pdf文件_java下载PDF文件
- python爬取网易云课程_Python爬取网易云课堂课程数据
- 【毕业设计】深度学习人脸表情识别系统 - python
- 圆角矩形不是圆:圆角的画法和二阶连续性
- 数据库与Java语言之间的鹊桥——JDBC
- Unity游戏图形渲染效果系列之阴影篇(一)
- 带LOG的二维码生成器
热门文章
- 2021年中国非晶合金行业产业链分析:非晶变压器有望成为下游行业应用主流[图]
- 对象克隆-深拷贝,浅拷贝,直接赋值
- 佳能相机MP4视频文件变小或打不开播放不了怎么修复
- 帐号泄露事件频发,到底什么样的密码才安全?
- 深度学习(Deep Ritz,Galerkin,PINN)求解偏微分方程(PDE)解读
- 神经网络学习(二):解常微分方程
- 天融信防火墙基础配置步骤
- Java基于SpringBoot+vue+nodejs 的宠物销售商城网站elementui
- 【从kitti开始自动驾驶】--6.2 全场景2D检测(移植至ROS,显示于RVIZ)
- rdma oracle,NFS Over RDMA