6.在c++程序中,如果一个整型变量频繁使用,最好将他定义为()
A.auto
B.extern
C.static
D.register
思路:寄存器快嘛,而且整型也正好能放进寄存器,详见变量的存储类型
7.长为n的字符串中匹配长度为m的子串的复杂度为()
A.O(N)
B.O(M+N)
C.O(N+logM)
D.O(M+logN)
思路:KMP算法的时间复杂度是O(M+N),但是BM算法会相对而言更快,但是也是O(M+N)。
当时选的是B,但是加个“最”总让人不放心,回来查看资料,用后缀数组的方法可以在O(M+LOGN)时间内完成,
但是这没有包含后缀数组预处理所需的时间(一般为NLOGN)。(ps:以后如果不确定还是跟着直觉走吧
8.判断一包含n个整数a[]中是否存在i、j、k满足a[i] + a[j] = a[k]的最小的时间复杂度为()
A. O(n3) B.O(n2lgn) C.O(n2) D.O(nlgn)
思路:O(N2)的算法能想一大堆,虽然最终我选的C,比如说用hash的话,三维遍历可以轻松编程二维遍历,但是总感觉是不是应该有nlgn的算法。
皇冠用户仓库开销:某淘宝金冠用户在多个城市有仓库,每个仓库的储货量不同,现在要通过货物运输,将每次仓库的储货量变成一致的,n个仓库之间的运输线路围城一个圈,运输只能在相邻的仓库之间进行,设计最小的运送成本(运货量*路程)
思路:这个在各种online-judge平台上都有答案,纯粹的数学问题,
如图,这是一个仓库分布的模拟,假设从第i个仓库向第i+1个仓库转移的物品为Pi个单位,其中Pi为负表示思是从i+1个仓库转移到第i个仓库,第n个仓库转移到第一个仓库即为Pn,设最后每个仓库平均后的货物为ave个单位,则有要最小化|P1|+|P2|+…+|Pi|+…+|Pn|
ave[i]=ave=A[i]-Pi+Pi-1
ave[1]=A[1]-P1+Pn
然后设W[i]=ave[i]-A[i]=-Pi+Pi-1
于是S[i]=W[1]+W[2]+….W[i]=Pn-Pi
即Pi=Pn-S[i] ,所以问题归结到最小化|Pn-S[1]|+|Pn-S[2]|+…+|Pn-S[n]|
所以Pn是S中位数的时候最小
#include<queue>
#include<string>
#include<pthread.h>
#include<algorithm>
#include<numeric>
using namespace std;
int s[10005];
int s2[10005];
int p[10005];
void findMinCost(int* arr,size_t n){
//nth_element(arr+1,arr+1+n/2,arr+1+n);
int sum=accumulate(arr+1,arr+1+n,0);
int ave=sum/n;
s[1]=ave-arr[1];
for(int i=2;i<n;++i){
s[i]=s[i-1]+ave-arr[i];
}
copy(s,s+n+1,s2);
nth_element(s2+1,s2+1+n/2,s2+n+1);
p[n]=s2[n/2+1];
for(int i=1;i<=n;++i){
p[i]=p[n]-s[i];
}
for(int i=1;i<=n;++i){
cout<<p[i]<<" " ;
}
cout<<endl;
}
int main(){
int arr[]={0,5,4,3,2,1};
findMinCost(arr,sizeof(arr)/sizeof(int)-1);
return 0;
}
第20题:字符串数组seq[] = a,b,c,d,aa,ba,ca,da,ab,bb,cb,db,ac...,aaa,aba,...
(1)aaa是第几个字符串
(2)ababacd是第几个
(3)第1000个字符串是什么
(4)编写函数find(),返回字符串在seq中是第几个(语言不限)
分析:
(1).长度,很容易推导出长度是n的字符串在第4^(n-1)个之后,aaa是1位和2位全排列后的第一个,即第4^(3-1)+4^(2-1)之后的第一个,也即第21个
(2)字符,每个字符可以判断出它之前的字符全排列了多少次,
字 符: a b a b a c d
全排列: 0 1 0 1 0 2 3
4^次幂: 0 1 2 3 4 5 6
即1*4^1+1*4^3+2*4^5+3*4^6 = 14405(考场不让用计算器...换成2的次幂来算)
(3)把1000转为二进制是 11 11 10 10 00
他们分别对应4进制里的 3 3 2 2 0
对应字符就是 d d c c a,倒序就是accdd,这里算出来的是1001的字符串
第1000个是上一个, 即 accdd-1 = dbcdd
(4)可执行代码如下:
- #include <iostream>
- #include <string>
- using namespace std;
- long find(char seq[]){
- long sum=1;
- long tmp=1;
- int len = strlen(seq);
- for (int i=0;i<len;i++)
- {
- sum+=(seq[i]-'a')*tmp;
- tmp*=4;
- }
- return sum;
- }
- int main(){
- cout<<find("ababacd")<<endl;
- cout<<find("dbcdd")<<endl;
- return 0;
- }
战报交流:战场上不同的位置有N个战士(n>4),每个战士知道当前的一些战况,现在需要这n个战士通过通话交流,互相传达自己知道的战况信息,每次通话,可以让通话的双方知道对方的所有情报,设计算法,使用最少的通话次数,是的战场上的n个士兵知道所有的战况信息,不需要写程序代码,得出最少的通话次数。
有N个人,其中一个明星和n-1个群众,群众都认识明星,明星不认识任何群众,群众和群众之间的认识关系不知道,现在如果你是机器人R2T2,你每次问一个人是否认识另外一个人的代价为O(1),试设计一种算法找出明星,并给出时间复杂度(没有复杂度不得分)。答案:
遍历 1~n 这n个人;
首先取出 1号 和 2号,
如果 1 认识 2, 那么把 1 去掉;
如果1不认识2,就可以把2去掉了。
每次比较都去掉一个,如此循环;n-1次之后只有一个人了
时间复杂度: O(n-1)