算法普及1

初识复杂度

时间复杂度表示程序运行占用时间的多少,是评估算法效率的重要指标。一般表示为关于 n 的某个函数。其中 n 往往对应输入数据的规模,用 T(n) 表示。

若有某个辅助函数 f(n) ,存在一个正常数 c 使得 f(n)×c>=T(n) 恒成立。记作 T(n)=O(f(n)) ,称 O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。

时间复杂度常用大 O 符号表述,不包括这个函数的低阶项和首项系数。

运行效率由低到高:

O(nn)>O(n!)>O(kn)>O(nk)>O(n n \sqrt{n} n)>O(nlog(n))>O(n)>O( n \sqrt{n} n)>O(log(n))>O(1)
t4:

最小周长

一个矩形的面积为S,已知该矩形的边长都是整数,求所有满足条件的矩形中,周长的最小值。例如:S = 24,那么有{1 24} {2 12} {3 8} {4 6}这4种矩形,其中{4 6}的周长最小,为20。

输入格式

输入1个数S(1 <= S <= 10^9)。

输出格式

输出最小周长。

输入样例

20

输出样例

20

思路

即求s被分解成两个最相近的整数的乘积
从1到 s \sqrt{s} s包含了其中一边的长度
为了使相邻两边差最小,从 s \sqrt{s} s开始向1找

代码

#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
	scanf("%d",&n);
	for(int i=sqrt(n);i>=1;i--)
		if(n%i==0){
			printf("%d",2*((n/i)+i));
			return 0;
		}
}

时间复杂度为O( n \sqrt{n} n)

和为K的倍数

小b喜欢和为K的倍数的序列。
现在有一个长度为n的序列A,请问A有多少个非空连续子序列是小b喜欢的。

输入格式

第一行输入一个正整数n; 第二行输入n个整数,表示A[i],以空格隔开; 第三行输入一个正整数K; 其中1≤n≤30000,对于任意A[i]有-10000≤A[i]≤10000,2≤K≤10000

输出格式

输出一个数,表示子序列的数目

输入样例

6
4 5 0 -2 -3 1
5

输出样例

7

思路

求连续非空子序列的话可以想到用前缀和
如果枚举的话还是O(n2)
如果(ai-aj)%k则ai%k-aj%k=0
对于每一种余数的情况,只用Cn2就可以算出
前缀和算上第0个数便于计算(ai-0)就是从a1加到ai

代码

#include<cstdio>
int n,k,t,a[30005],sum=0,cnt[10005];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&t);
		a[i]=a[i-1]+t;
	}
	scanf("%d",&k);
	for(int i=0;i<=n;i++)
		cnt[(a[i]%k+k)%k]++;//防止负数越界,统计每种余数的数量
	for(int i=0;i<k;i++)
		sum+=(cnt[i]-1)*cnt[i]/2;
	printf("%d",sum);
}

时间复杂度为O(n+k)

数字1的数量

给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数。
例如:n = 12,包含了5个1。1,10,12共包含3个1,11包含2个1,总共5个1。

输入格式

输入N(1 <= N <= 10^9)

输出格式

输出包含1的个数

输入样例

12

输出样例

5

思路

O(n)肯定不行,可以考虑每一位的1出现的次数
如果当位数字大于等于2

----------------------------------------------------------------------------------------------------------------------

 

posted @ 2022-09-26 18:06  _LLD  阅读(23)  评论(0)    收藏  举报  来源