一、算法分析
算法是解决问题的方法与步骤。
在看一个算法是否优秀时,我们一般要考虑一个算法的时间复杂度和空间复杂度。
常见的时间复杂度:O(1)、O(logn)、O(n)、O(nlogn)、O(n^2)、O(2^n)、O(n!);
(1) 时间复杂度:算法的执行效率
例1: 时间复杂度为O(1)(常数级别)
int fun(int n)
{
int i = n;
int j = 3 * n;
return i + j;
}
例2: 时间复杂度为O(logn)
设while循环执行了x次,即2^x=n,解得x = log2(n)
int fun(int n)
{
int i = 1;
while(i <= n)
i = i * 2;
return i;
}
例3: 时间复杂度为O(n)
int fun(int n)
{
sum = 0;
for(int i = 0;i < n;i++)
sum += i;
return sum;
}
例4: 时间复杂度为O(m+n)
int fun(int m,int n)
{
int sum = 0;
for(int i = 1;i <= m;i++)
sum += i;
for(int i = 2;i <= n;i++)
sum += i;
return sum;
}
例5: 时间复杂度为O(mlogn)
int fun(int m,int n)
{
sum = 0;
for(int i = 0;i < m;i++)
{
for(int j = 0;j < n;j++)
{
sum += i * j;
j = j * 2;
}
}
return sum;
}
例6: 时间复杂度为O(n^2)
int fun(int n)
{
sum = 0;
for(int i = 0;i < n;i++)
{
for(int j = 0;j < n;j++)
{
sum += i * j;
}
}
return sum;
}
常见的时间复杂度:O(1) < O(logn) < O(n) < O(nlogn) < O(n ^ 2) < O( 2 ^ n) < O(n!)
通常情况下,竞赛环境中要求运行时间为1秒。计算机1秒可以执行的次数为10亿次。
(2) 空间复杂度:算法所占内存空间
例1: 空间复杂度为O(1)
int fun(int n)
{
sum=0;
for(int i = 0;i < n;i++)
sum += i;
return sum;
}
例2: 空间复杂度为O(n)
int fun(int n)
{
int arr[N];
while(i <= N)
i = i * 2;
return i;
}
例3: 空间复杂度为O(mn)
int fun(int m,int n)
{
int arr[M][N];
for(int i = 1;i <= m;i++)
for(int j = 1;j <= n;j++)
sum += arr[i][j];
return sum;
}
常见的空间复杂度:O(1) < O(n) < O(n^2)
二、信息的表示和储存
学习目标
1.熟悉二进制原理,掌握各种进制的相互转换
2.熟知常用字符的编码(ASCII)
3.熟练储存单位的换算
4.熟练运用源码、反码、补码
(1)二进制原理
计算机内部采用二进制代码(0和1)存储信息
比特(b)是储存信息的最小单位。
(2)正整数的二进制、十进制、十六进制的转换
十进制数转换为N进制数
除基(N)取余、逆序输出
例(11)D 1011B
(23)4
B H
N进制数转换为十进制数
按权展开、逐项相加
例(1101)B 13D
(3)正整数的二进制、十进制、十六进制的转换
十进制小数转换为N进制数
小数部分乘以N,取整数部分直至小数点后为0
例(0.125)D (0.001)2
(0.02)4
(0.1)8
(0.2)H
N进制小数转换为十进制数
位权展开,逐项相加
例(0.101)B (0.625) D
(4)字符编码和存储单位
ASCII码
包括字母、数字、常用符号的全球通用编码方法用7个二进制位来表示一个字符,最多表示128个字符3小写字母比对应的大写字母的ASClI码值大32
例如,“回车符”的ASCII码为0001101
"A”的ASCII码为1000001
“a”的ASCII码为1100001
字节(B)是存储的基本单位
a) 1个字节(byte,简写成B)=8个二进制位
b) 即1B=8b
c)1KB=1024B,1MB=1024KB,1GB=1024MB
1TB=1024GB
d) 1个汉字占2个字节
e) 1个字母、数字、标点符号占1个字节
(5)计算机中整数的表示方法
有符号数 1)原码
2)反码
3)补码
最高位表正负,0表正,1表负
对于正数,原码=反码=补码
对于负数,反码=将原码的各位取反(符号位除外);补码等于反码加一
例1∶原码01000101
例2∶原码11000101
反码10111010
补码10111011
1.(A1.4) =(161.25) D=(10100001.01) B
2. (1100010.001) B=(98.125) D=(62.2) H
3.A35 -1C= (19) H,(24D)16+(53)16=(2A0)16
4.8位无符号数在计算机内部能表达的数有多少种?最大能表示多大的数?如果是有符号的数呢?如
是n位呢?
无符号:2^8种,2^8 - 1 2^n种,2^n - 1
有符号:2^7种,2^7 - 1 2^(n-1)种,2(n-1) - 1
1.B 2.B 3.C
4.A 5. A 6.B 7.A
8.D 9.D 10.A
11.D 12.略
例:编程实现将十进制数n转换为二进制数
#include <cstdio>
#include <cstdlib>
using namespace std;
int main()
{
int a[32];
int n,i;
scanf("%d",&n);
while (n > 0)
{
a[i] = n % 2;
i++;
n = n / 2;
}
for (int j = i - 1;j >= 0;j--)
printf("%d",a[j]);
return 0;
}
三、秦九韶算法
例如,对于一元五次多项式,如果利用传统的方法计算f(4)的值,需要计算4 ^ 5, 4 ^ 4,4 ^ 3,4 ^ 2,4 ^ 1,即
执行1+2+3+4+5次乘法,对于一元n次多项式,需要执(1+2+3+4+5+6+7+…
…+n) = (1+n)n/2次乘法,时间复杂度为O(nxn)。
例题:
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
int main()
{
int n,ans = 0,i = 0;
char s[32];
scanf("%d\n",&n);
gets(s);
int len = strlen(s);
ans = s[0]-'0';
for(int i=1;i<len;i++)
ans = ans*n+s[i]-'0';
printf("%d",ans);
return 0;
}