题目1:一个农夫养了一批怪牛,一对牛每月繁殖一对小牛,小牛出生后三个月时间来生长,第四个月来繁殖。
输入牛的组数 n, 然后在输入 n 组,每组由两行组成:第一行是牛的对数,第二行是需要的成长时间;如此依次输入 n 组。
{
int m_nKey;
ListNode* m_pNext;
};先翻转链表,再按顺序打印(主要是想自己实现单链表的翻转,这种实现方式破坏了链表的结构,当然再翻转一下就还原了) 翻转链表的步骤: 1:将当前节点的next节点指向他以前的前一个节点 2:当前节点下移一位 3:如果是最后一个节点,就把它的next节点指向它以前的前一个节点,并推出循环。
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
其中最大的是:
4 5
5 3
要求:(1) 写出算法;(2) 分析时间复杂度;(3) 用 C 写出关键代码
每个实部和虚部的系数最大值不超过 1000 输出描述: 求卷积多项式系数输出;先输出高阶系数,多项式算法.
1 #include
2 #include
3 using namespace std;
4
5 int cow(int month_num)
6 {
7 if (month_num<=4)
8 return month_num+1;
9 else
10 return cow(month_num-1)+cow(month_num-4);
11 }
12 int main()
13 {
14 int num,num_cow,month_num=0;
15 vector<int> num_sr;
16 vector<int>::iterator it;
17
18 cin>>num;
19 for(int i=1;i<=2*num;++i)
20 {
21 cin>>num_cow;
22 num_sr.push_back(num_cow);
23 }
24 for(it=num_sr.begin();it<=num_sr.end()-2;)
25 {
26 //cout<
27 int num_total=cow(*(++it));
28 //cout<
29 //注意此处,上面的++it对迭代器进行了+1操作,it此时已经指向了it+1
30 cout<endl;
31 it=it+2;
32 }
33 while(1);
34 }
题目2:输入一个字符串,输出该字符串中对称的子字符串的最大长度,比如输入字符串 “12213”,由于该字符串里最长的对称子字符串是 “1221”,因此输出为 4。
输入描述:
连续的字符串,字符串长度不超过 64,只包含数字和字母
输出描述:
最长的对称字符串长度
输入示例: 12321abc 输出示例: 5
import java.util.Scanner;
public class Main {
public static int GetlongestSymStr(String str){
int n=str.length();
boolean[][] dp=new boolean[n][n];
int maxLen=0;
for(int i=0;i
for(int j=i;j>=0;j--){
if(str.charAt(i)==str.charAt(j) && (i-j<2 || dp[j+1][i-1]==true)){
dp[j][i]=true;
maxLen=Math.max(maxLen, i-j+1);
}
}
}
return maxLen;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
System.out.println(GetlongestSymStr(s));
}
}
题目3:华为应用市场举办安装应用奖励金币活动,不同的应用下载、试玩需要的流量大小不同,奖励的金币数量也不同,同一个应用多次下载只奖励一次金币,小花月末有一定的余量,计算下载哪些应用可以获取的金币最多?相同金币情况下,优先排名靠前的应用。
输入描述:
输入分三行
第一行:流量数,单位 MB, 整数
第二行:应用排名顺序,下载、试玩需要流量数,单位 MB, 整数
第三行:应用奖励的金币数
输出描述:
输出应用列表:建议下载的应用顺序号,用一个空格分隔
输入示例:
40
12 13 23 36
11 11 20 30
输出示例:
1 3
说明:注意输出:开头、末尾没有空格
import java.util.Scanner;
public class Main{
/**
* @param numOfLL 剩余流量数
* @param needLL 下载应用排名及消耗流量数
* @param reword 下载奖励金币数
* @return
*/
public static String SequenceOfDownload(int numOfLL,int[] needLL,int[] reword){
return ZeroOnePack(numOfLL,needLL.length,needLL,reword);
}
/**
* @param V 背包容量
* @param N 物品种类
* @param weight 物品重量
* @param value 物品价值
* @return
*/
public static String ZeroOnePack(int V,int N,int[] weight,int[] value){
//初始化动态规划数组
int[][] dp = new int[N+1][V+1];
//为了便于理解,将dp[i][0]和dp[0][j]均置为0,从1开始计算
for(int i=1;i1;i++){
for(int j=1;j1;j++){
//如果第i件物品的重量大于背包容量j,则不装入背包
//由于weight和value数组下标都是从0开始,故注意第i个物品的重量为weight[i-1],价值为value[i-1]
if(weight[i-1] > j)
dp[i][j] = dp[i-1][j];
else
dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-weight[i-1]]+value[i-1]);
}
}
//则容量为V的背包能够装入物品的最大值为
int maxValue = dp[N][V];
//逆推找出装入背包的所有商品的编号
int j=V;
String numStr="";
for(int i=N;i>0;i--){
//若果dp[i][j]>dp[i-1][j],这说明第i件物品是放入背包的
if(dp[i][j]>dp[i-1][j]){
numStr = i+" "+numStr;
j=j-weight[i-1];
}
if(j==0)
break;
}
return numStr;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int numOfLL = Integer.parseInt(sc.nextLine());
String str2 = sc.nextLine();
String str3 = sc.nextLine();
String[] needLL;
String[] reword;
needLL= str2.split(" ");
reword = str3.split(" ");
int[] Reword = new int[needLL.length];
int[] NeedLL = new int[reword.length];
for(int i=0;i
NeedLL[i] = Integer.parseInt(needLL[i]);
Reword[i] = Integer.parseInt(reword[i]);
}
String result = SequenceOfDownload(numOfLL,NeedLL,Reword);
result = result.substring(0,result.length()-1);
System.out.println(result);
sc.close();
}
}
题目4:输入一个链表的头结点,从尾到头反过来输出每个结点的值。
链表结点定义如下:
struct ListNode{
int m_nKey;
ListNode* m_pNext;
};先翻转链表,再按顺序打印(主要是想自己实现单链表的翻转,这种实现方式破坏了链表的结构,当然再翻转一下就还原了) 翻转链表的步骤: 1:将当前节点的next节点指向他以前的前一个节点 2:当前节点下移一位 3:如果是最后一个节点,就把它的next节点指向它以前的前一个节点,并推出循环。
void reverse()
{
if(NULL==head || NULL==head->next)
{
return;
}
cur=head->next;
node* prev=NULL;
node* pcur=head->next;
node* next;
while(pcur!=NULL)
{
if(pcur->next==NULL)
{
pcur->next=prev;
break;
}
next=pcur->next;
pcur->next=prev;
prev=pcur;
pcur=next;
}
head->next=pcur;
node* tmp=head->next;
while(tmp!=NULL)
{
cout<data<<"\t";
tmp=tmp->next;
}
}
void print3()
{
recursion(head->next);
}
题目5:求一个矩阵中最大的二维矩阵 (元素和最大)。
如:1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
其中最大的是:
4 5
5 3
要求:(1) 写出算法;(2) 分析时间复杂度;(3) 用 C 写出关键代码
#include
//O(row * col)int sumMat(int * in, int row, int col, int *r, int * c)
{
int sum = 0;
for(int i = 0; i < row - 1; i++)
{
int sumt = 0;
int * r1 = in + i * col;
int * r2 = in + (i + 1) * col;
for(int j = 0; j < col - 1; j++)
{
sumt = r1[j] + r2[j] + r1[j + 1] + r2[j + 1];
if(sumt > sum)
{
*r = (i + 1);
*c = (j + 1);
sum = sumt;
}
}
}
return sum;
}
int main()
{
int a[15] = {1,2,0,3,4,2,3,4,5,1,1,1,5,3,0};
int sum, r, c;
sum = sumMat(a, 3, 5, &r, &c); //r c返回最大二维矩阵的位置
return 0;
}
题目6:给定一个字符串 str,求其中全部整数数字之和。
输入描述:
1、忽略小数点,例如”A1.2”,认为包含整数 1 和 2;
2、如果整数的左侧出现字符 “-“,则奇数个认为是负整数,偶数个认为是正整数。
例如”AB-1CD- -2EF- - -3” ,认为包含整数 - 1、2 和 - 3。
(注意:这里的”-“与”-“间是连续的,没有空格隔开)
输出描述:
输出即为字符串中所有整数数字之后。
import sys
a = sys.stdin.readline()
sum,num,pos=0,0,1
if a=='':
print 0
for i in xrange(0,len(a)):
if 48<= ord(a[i])<57:
num=num*10+int(a[i])*pos
else:
sum+=num
num=0
if a[i]=='-':
if i-1>-1 and a[i-1]=='-':
pos=-pos
else :
pos =-1
else:
pos=1
sum+=num
print sum
题目7:多项式 的系数 [b (2) b (1) b (0)]=[1 2 5]
二者相乘所得的多项式 的系数 [c (3) c (2) c (1) c (0)]=[1 3 7 5]
利用上面的计算方法,我们很容易得到:
c(0)=a(0)b(0)
c(1)=a(0)b(1)+a(1)b(0)
c(2)=a(0)b(2)+a(1)b(1)+a(2)b(0)
c(3)=a(0)b(3)+a(1)b(2)+a(2)b(1)+a(3)b(0)
其中:a (3)=a (2)=b (3)=0
在上面的基础上推广一下:
假定两个多项式的系数分别为 a (n),n=0~n1 和 b (n),n=0~n2,这两个多项式相乘所得的多项式系数为 c (n),则:
c(0)=a(0)b(0)
c(1)=a(0)b(1)+a(1)b(0)
c(2)=a(0)b(2)+a(1)b(1)+a(2)b(0)
c(3)=a(0)b(3)+a(1)b(2)+a(2)b(1)+a(3)b(0)
c(4)=a(0)b(4)+a(1)b(3)+a(2)b(2)+a(3)b(1)+a(4)b(0)
以此类推可以得到卷积算法:
上面这个式子就是 a (n) 和 b (n) 的卷积表达式。
通常我们把 a (n) 和 b (n) 的卷积记为:a (n)b (n),其中的表示卷积运算符
输入描述:
两个最高阶数为 4 的复数多项式系数序列。高阶系数先输入;每个系数为复数,复数先输入实数部分,再输入虚数部分; 实部或者虚部为 0,则输入为 0;每个实部和虚部的系数最大值不超过 1000 输出描述: 求卷积多项式系数输出;先输出高阶系数,多项式算法.
输入示例: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 输出: 0 2 0 4 0 6 0 8 0 10 0 8 0 6 0 4 0 2
import java.io.*;
import java.util.*;
class Test {
}
public class Main
{
public static class Complex {
public int real;
public int image;
public Complex(int real,int image){
this.real = real;
this.image = image;
}
public static Complex mul(Complex c1,Complex c2){
int newReal = c1.real * c2.real - c1.image * c2.image;
int newImage = c1.real * c2.image + c1.image * c2.real;
return new Complex(newReal, newImage);
}
public static Complex add(Complex c1, Complex c2){
return new Complex(c1.real+c2.real,c1.image+c2.image);
}
public void show(){
System.out.println(real);
System.out.println(image);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Complex[] a = new Complex[5];
Complex[] b = new Complex[5];
for(int i=0;i<5;i++){
a[i] = new Complex(sc.nextInt(),sc.nextInt());
}
for(int i=0;i<5;i++){
b[i] = new Complex(sc.nextInt(),sc.nextInt());
}
for(int i = 8; i >=0; i--){
getOne(i, a, b).show();
}
}
//计算多项式的一项
public static Complex getOne(int index, Complex[] a, Complex[] b){
Complex res = new Complex(0,0);
for(int k = 0;k < 5;k++){
if(4 - k>index){
continue;
}
else{
if(index - 4 + k > 4){
break;
}
else{
Complex cur = Complex.mul(a[k],b[8 - index - k]);
res.real += cur.real;
res.image += cur.image;
}
}
}
return res;
}
}
题目8:有两个序列 a,b,大小都为 n, 序列元素的值任意整数,无序;要求:通过交换 a,b 中的元素,使 [序列 a 元素的和] 与 [序列 b 元素的和] 之间的差最小。
例如: var a=[100 ,99 ,98 ,1 ,2 ,3]; var b=[1, 2, 3, 4, 5, 40]; 有两个序列 a,b,大小都为 n, 序列元素的值任意整数,无序; 要求:通过交换 a,b 中的元素,使 [序列 a 元素的和] 与 [序列 b 元素的和] 之间的差最小。第一种算法: 当前数组 a 和数组 b 的和之差为 A = sum(a) - sum(b) a 的第 i 个元素和 b 的第 j 个元素交换后,a 和 b 的和之差为 A' = sum(a) - a[i] + b[j] - (sum(b)- b[j] + a[i]) = sum(a) - sum(b) - 2 (a[i] - b[j]) = A - 2 (a[i] - b[j]) 设 x= a [i] - b [j] |A| - |A'| = |A| - |A-2x| 假设 A> 0,当 x 在 (0,A) 之间时,做这样的交换才能使得交换后的 a 和 b 的和之差变小,x 越接近 A/2 效果越好,如果找不到在 (0,A) 之间的 x,则当前的 a 和 b 就是答案。 所以算法大概如下: 在 a 和 b 中寻找使得 x 在 (0,A) 之间并且最接近 A/2 的 i 和 j,交换相应的 i 和 j 元素, 重新计算 A 后,重复前面的步骤直至找不到 (0,A) 之间的 x 为止。 第二种算法: 1. 将两序列合并为一个序列,并排序,为序列 Source 2. 拿出最大元素 Big,次大的元素 Small 3. 在余下的序列 S [:-2] 进行平分,得到序列 max,min 4. 将 Small 加到 max 序列,将 Big 加大 min 序列,重新计算新序列和,和大的为 max,小的为 min。 a={1,2,3,4,5} b={6,7,8,9,10} s={1,2,3,4,5,6,7,8,9,10} a={1,3,6,7,10} b={2,4,5,8,9} 第一种解法源码如下:
#include
using namespace std;
class RunClass
{
public:
void BalanceArray( int array1[], int array2[],int n1,int n2);
private:
int Sum(int array[],int n);
};
void RunClass::BalanceArray(int array1[], int array2[],int n1,int n2)
{
if (n1 != n2)
return;
int *array=new int[n1];
if (Sum(array1,n1) < Sum(array2,n2))
{
array= array1;
array1 = array2;
array2 = array;
}
bool ifCycle = true;
int length = n1;
while (ifCycle)
{
ifCycle = false;
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
int itemValue = array1[i] - array2[j];
int sumValue = Sum(array1,n1) - Sum(array2,n2);
if (itemValue < sumValue && itemValue > 0)
{
ifCycle = true;
int item = array1[i];
array1[i] = array2[j];
array2[j] = item;
}
}
}
}
}
int RunClass::Sum(int array[],int n)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += array[i];
}
return sum;
}
int main(){
int array1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 90, 0, 0, 100 };
int array2[] = { -1, -2, -100, -3, 99, -222, -2, -3, -5, -88, 11, 12, 13 };
RunClass a;
a.BalanceArray(array1, array2,13,13);
for(int i=0;i<13;i++)
cout<" ";
cout<<endl;
for(int i=0;i<13;i++)
cout<" ";
cout<<endl;
return 0;
}
题目9:老师想知道从某某同学当中,分数最高的是多少,现在请你编程模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
输入描述:
输入包括多组测试数据。
每组输入第一行是两个正整数 N 和 M(0 < N <= 30000,0 < M < 5000), 分别代表学生的数目和操作的数目。
学生 ID 编号从 1 编到 N。
第二行包含 N 个整数,代表这 N 个学生的初始成绩,其中第 i 个数代表 ID 为 i 的学生的成绩
接下来又 M 行,每一行有一个字符 C(只取‘Q’或‘U’),和两个正整数 A,B, 当 C 为 'Q' 的时候,表示这是一条询问操作,他询问 ID 从 A 到 B(包括 A,B)的学生当中,成绩最高的是多少
当 C 为‘U’的时候,表示这是一条更新操作,要求把 ID 为 A 的学生的成绩更改为 B。
输出描述:
对于每一次询问操作,在一行里面输出最高成绩
输入例子:
5 7
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 4 5
U 2 9
Q 1 5
输出例子:
5
6
5
9
#include
#include
#include
using namespace std;
int main(){
int i;
int n, m, num[100];
while (cin >> n >> m)
{
vector<int> score(n);
//录入成绩
for (i = 0; i < n; i++)
{
cin >> score[i];
}
int a, b;
char str;
int j = 0;
for (i = 0; i < m; i++)
{
cin >> str >> a >> b;
if (str == 'U')
score[a - 1] = b;
if (str == 'Q')
{
if (a > b)
swap(a, b);
num[j]= *max_element(score.begin() + a - 1, score.begin() + b);
j++;
}
}
for (i = 0; i < j; i++)
cout << num[i] << endl;
}
getchar();
getchar();
return 0;
}
题目10:开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
- 记录最多 8 条错误记录,对相同的错误记录 (即文件名称和行号完全匹配) 只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
- 2. 超过 16 个字符的文件名称,只记录文件的最后有效 16 个字符;(如果文件名不同,而只是文件名的后 16 个字符和行号相同,也不要合并)
- 输入的文件可能带路径,记录文件名称不能带路径
#include
#include
#include
#include
#include
using namespace std;
string GetKey(string fn) //找到文件名{
int pos = fn.rfind('\\');
return fn.substr(pos + 1);
}
string GetPart(string n) //找到文件名的后16个字符{
int pos = n.rfind(" ");
return n.substr(max(0, pos - 16), min(16, pos)) + n.substr(pos);
//substr是C++语言函数,主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。
}
struct item
{
string key;
int cc;
item(string k) :key(k), cc(1)
{}
};
bool compare(item a, item b)//确定compare是true还是false,确定是升序还是降序排列{
return a.cc>b.cc ? true : false;
}
int main(){
map<string, int> strToindex;
vector vc;
string str_in;
while (getline(cin, str_in))
{
if (str_in.size() == 0)
break;
string key = GetKey(str_in);//将文件名赋值给key
if (strToindex.count(key) == 0)//count函数,C++标准模板库函数,用于统计某一值在一定范围内出现的次数
{
strToindex.insert(make_pair(key, vc.size()));
vc.push_back(item(key));
}
else
vc[strToindex[key]].cc++;
}
stable_sort(vc.begin(), vc.end(), compare);//升序排列
int cc = 0;
for (int i = 0; i
{
cout << GetPart(vc[i].key) << " " << vc[i].cc << endl;
cc++;
if (cc >= 8)
break;
}
return 0;
}
计算机视觉常见面试题型介绍及解答
第一期 | 第二期 | 第三期 | 第四期 | 第五期 |
第六期 | 第七期 | 第八期 | 第九期 | 第十期 | 第11期
腾讯算法工程师笔试真题介绍及解析汇总合集
第一期 | 第二期 | 第三期 | 第四期 | 第五期
阿里算法岗位最新编程题介绍及解析
第一期 | 第二期 | 第三期 | 第四期 | 第五期 | 第六期 | 第七期
华为研发工程师编程题型介绍及解析
第一期 | 第二期 | 第三期 | 第四期 | 第五期 |
第六期 | 第七期 | 第八期 | 第九期 | 第十期 |