2018 校招在线编程 20题-01
1. 最大乘积(拼多多)
输入 3 4 1 2 输出 24
解题思路:
定义五个数,一个最大,一个次大,一个第三大,一个最小,一个次小。
只要找到这五个数,问题就解决了。因为最大乘积只可能是
最大*(次大*第三大) 或者是 最大*(最小*次小)。时间复杂度O(n),
空间复杂度O(1)。PS:这道题输入有问题,题目给的样例是直接给了一组数,
而此时用例先给了一个数的个数n,然后再给了一组数。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int n,ele; 6 cin>>n; 7 if(n<3) //数组中至少要有3个数存在 8 return -1; 9 10 long long min_fir = INT_MAX, min_sec = INT_MAX; //必须定义成long long,int的话在计算乘法的时候会溢出 11 long long max_fir = INT_MIN, max_sec = INT_MIN, max_thi = INT_MIN; 12 long long res,tmp; 13 for(int i=0;i<n;i++){ 14 cin>>ele; 15 //寻找两个最小 16 if(ele<min_fir){ 17 min_sec = min_fir; 18 min_fir = ele; 19 }else if(ele<min_sec){ 20 min_sec = ele; 21 } 22 23 //寻找三个个最大 24 if(ele>max_fir){ 25 max_thi = max_sec; 26 max_sec = max_fir; 27 max_fir = ele; 28 }else if(ele>max_sec){ 29 max_thi = max_sec; 30 max_sec = ele; 31 }else if(ele>max_thi){ 32 max_thi = ele; 33 } 34 } 35 res = max_fir*max_sec*max_thi; 36 tmp = max_fir*min_fir*min_sec; 37 38 res = res>tmp? res:tmp; 39 //res = max(max_fir*max_sec*max_thi,max_fir*min_fir*min_sec); 40 //res = max_fir*max_sec*max_thi>max_fir*min_fir*min_sec?max_fir*max_sec*max_thi:max_fir*min_fir*min_sec; 41 cout<<res<<endl; 42 return 0; 43 }
注意:数据类型定义成long long,否则会溢出。存储的五个变量值也应该定义成long long,虽然其本身是int,但是计算乘积时,3个int的结果仍然是int,会溢出。再把溢出后的结果赋值给long long类型,并不能拯救溢出。
2. 彩色的砖块(网易)简单
输入 ABAB 输出 2
解题思路:
对每种颜色砖块个数做统计:
- 如果出现了两种以上的颜色,肯定最少有两种相邻,直接输出0.
- 如果出现了一种,那就只有一种。
- 如果出现了两种,那就只有两种。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 string s; 6 cin>>s; 7 int length; 8 //cin>>length; //输入有问题,不使用该值 9 unordered_set<char> cset; 10 length = s.size(); 11 for(int i=0;i<length;i++){ 12 cset.insert(s[i]); 13 } 14 15 if(cset.size()==1) 16 cout<<1<<endl; 17 else if(cset.size()==2) 18 cout<<2<<endl; 19 else // if(s.size()==1) 20 cout<<0<<endl; 21 22 return 0; 23 }
注:题目并没有给length值,自己计算
3. 等差数列(网易) 简单
输入 3 3 1 2 输出 Possible
解题思路:
排序,判断相邻数字的差是否相等
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int n,tmp; 6 cin>>n; 7 vector<int> vec(n); 8 for(int i=0;i<n;i++){ 9 cin>>tmp; 10 vec[i]=tmp; 11 } 12 int size = vec.size(); 13 if(size==1) 14 cout<<"Possible"<<endl; 15 sort(vec.begin(),vec.end()); 16 17 bool flag = true; 18 tmp = vec[1]-vec[0]; 19 for(int i=1;i<size-1;i++){ 20 int diff = vec[i+1]-vec[i]; 21 if(diff!=tmp){ 22 flag = false; 23 break; 24 } 25 } 26 27 if(flag == true) 28 cout<<"Possible"<<endl; 29 else 30 cout<<"Impossible"<<endl; 31 return 0; 32 }
4. 交错01串(网易)简单
输入 111101111 输出 3
解题思路:
遍历一边数组,res记录子串长度,maxl记录最大的子串长度
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 string s; 6 cin>>s; 7 int len = s.size(); 8 if(len<1) 9 cout<<0<<endl; 10 int res = 1, maxl = 1; 11 12 for(int i=1;i<len;i++){ 13 if(s[i]!=s[i-1]){ 14 res++; 15 }else{ 16 res = 1;//当前作为一个字符 17 } 18 if(res>maxl){ 19 maxl = res; 20 } 21 } 22 23 cout<<maxl<<endl; 24 return 0; 25 }
5. 操作序列(网易)找规律-简单
输入 4 1 2 3 4 输出 4 2 1 3
解题思路:
输入:1 2 3 4
输出:4 2 1 3
输入:1 2 3 4 5 6
输出:6 4 2 1 3 5
输入:1 2 3 4 5
输出:5 3 1 2 4
规律:从最后一个元素往前,每隔一个元素输出,然后剩下的元素,从前往后输出
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int n; 6 cin>>n; 7 vector<string> s(n); 8 //string s=""; 9 //读入数据 10 string tmp; 11 for(int i=0;i<n;i++){ 12 cin>>tmp; 13 s[i]=tmp; 14 } 15 16 if(n==1) 17 cout<<s[0]<<endl; 18 19 for(int i=n-1;i>=0;i=i-2){ 20 cout<<s[i]<<" "; 21 } 22 int j = ((n&1)==1); 23 for(;j<n-2;j=j+2){ 24 cout<<s[j]<<" "; 25 } 26 cout<<s[j]<<endl; //行末没有空格 27 return 0; 28 }
注意边界:N=1的时候直接输出,最后一个元素不输出空格,因为题目要求行末没有空格
//规律题 //n = 1,b = 1 n = 1直接输出 //n = 2,b = 2,1 //n = 3,b = 3,1,2 //n = 4,b = 4,2,1,3 //n = 5,b = 5,3,1,2,4 //n = 6,b = 6,4,2,1,3,5 //由上述可推,当n 为奇数时, //先从后向前输出奇数位置的数字,再从前向后输出偶数位置的数字 //当n 为偶数时 //先从后向前输出偶数位置的数字,再从前向后输出奇数位置的数字
6. 独立的小易(网易)简单
输入 3 5 100 10 输出 11
解题思路:
提供水果f,只需支付房费x
水果用光,支付水果f+房费x
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int x,f,d,p,days; 6 cin>>x>>f>>d>>p; 7 8 days = min(f,d/x); 9 f = f - days; 10 d = d - days*x; 11 12 if(f==0){ //不等于0,直接返回days即可 13 days += d/(x+p); 14 } 15 16 cout<<days<<endl; 17 return 0; 18 }
7. 大数相乘(拼多多)
输入 72106547548473106236 982161082972751393 输出 70820244829634538040848656466105986748
解题思路:
按照乘法运算求解,两个数的每一位对应相乘。模拟手算过程
1 链接:https://www.nowcoder.com/questionTerminal/0f0badf5f2204a6bb968b0955a82779e 2 来源:牛客网 3 4 #include<stdio.h> 5 #include<string> 6 #include<iostream> 7 using namespace std; 8 const int L=11000; 9 string mul(string,string); 10 int main(){ 11 string x,y; 12 while(cin>>x>>y) 13 cout<<mul(x,y)<<endl; 14 } 15 string mul(string a,string b) { 16 string s; 17 int na[L],nb[L],nc[L],La=a.size(),Lb=b.size(),i,j; 18 fill(na,na+L,0);fill(nb,nb+L,0);fill(nc,nc+L,0); 19 for(i=La-1;i>=0;i--) na[La-i]=a[i]-'0'; 20 for(i=Lb-1;i>=0;i--) nb[Lb-i]=b[i]-'0'; 21 for(i=1;i<=La;i++) 22 for(j=1;j<=Lb;j++) 23 nc[i+j-1]+=na[i]*nb[j]; 24 for(i=1;i<=La+Lb;i++) 25 nc[i+1]+=nc[i]/10,nc[i]%=10; 26 if(nc[La+Lb]) s+=nc[La+Lb]+'0'; 27 for(i=La+Lb-1;i>=1;i--) 28 s+=nc[i]+'0'; 29 return s; 30 }
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 string multiplyOfString(string s1, string s2) 5 { 6 string res(s1.size()+s2.size(),'0'); 7 string shorter = s1.size() < s2.size() ? s1 : s2; 8 string longer = s1.size() < s2.size() ? s2 : s1; 9 for (int i = shorter.size() - 1; i >= 0; --i) 10 { 11 int carry = 0;//进位 12 for (int j = longer.size() - 1; j >= 0; --j) 13 { 14 int temp = (longer[j] - '0')*(shorter[i] - '0')+ carry + res[i+j+1] - '0'; 15 res[i + j + 1] = temp % 10 + '0'; 16 carry = temp / 10; 17 if (carry&&j == 0)//如果短串已经到最左边(j==0)并且carry是不为0的,那么res要修改; 18 res[i] += carry; 19 } 20 } 21 //去掉前排的0 22 int i = 0; 23 while (res[i] == '0')//此处不要写i++; 24 res.erase(0, 1); 25 return res; 26 } 27 28 int main() 29 { 30 string s1, s2; 31 cin >> s1 >> s2; 32 cout << multiplyOfString(s1, s2) << endl; 33 }
我自己的代码实现:
8. 六一儿童节(拼多多)简单
输入 3 2 2 3 2 3 1 输出 1
解题思路:
对两个数组排序
h : 2 3 4 6 8
w: 1 3 5 7
从后往前比较,双指针。当w>=h时,两者同时向前移动,且人数加1。当w<h时,w不动,h向前移动。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int n,m; 6 double tmp; 7 cin>>n; 8 vector<double> h(n,0); 9 for(int i=0;i<n;i++){ 10 cin>>tmp; 11 h[i]=tmp; 12 } 13 14 cin>>m; 15 vector<double> w(m,0); 16 for(int i=0;i<m;i++){ 17 cin>>tmp; 18 w[i]=tmp; 19 } 20 21 sort(h.begin(),h.end()); 22 sort(w.begin(),w.end()); 23 24 int res = 0; 25 while(m>0 && n>0){ 26 if(w[m-1]>=h[n-1]){ 27 m--; 28 n--; 29 res++; 30 }else{ 31 n--; 32 } 33 } 34 cout<<res<<endl; 35 return 0; 36 }
9. 疯狂队列(网易)
输入 5 5 10 25 40 25 输出 100
解题思路:
区分奇数个元素及偶数个元素,使用双指针
偶数个元素:
1 2 3 4 5 6
1 6 -> 5 2 -> 3 4 即 3【5(1 6)2】4
奇数个元素:
1 2 3 4 5
1 5 -> 4 2 -> 3(单独判断是插入队头还是队尾)
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int n,tmp; 6 cin>>n; 7 vector<int> arr(n,0); 8 9 for(int i=0;i<n;i++){ 10 cin>>tmp; 11 arr[i]=tmp; 12 } 13 sort(arr.begin(),arr.end()); 14 15 deque<int> d; 16 int cnt = 0; 17 int i=0,j=n-1; 18 19 while(i<j){ 20 if((cnt&1)==0){ 21 d.push_back(arr[j--]); 22 d.push_front(arr[i++]); 23 }else{ 24 d.push_back(arr[i++]); 25 d.push_front(arr[j--]); 26 } 27 cnt++; 28 } 29 30 if(i==j){ 31 if(abs(arr[i]-d[0])>abs(arr[i]-d[n-2])) 32 d.push_front(arr[i]); 33 else 34 d.push_back(arr[i]); 35 } 36 cnt=0; 37 for(int i=1;i<n;i++){ 38 cnt += abs(d[i]-d[i-1]); 39 } 40 41 cout<<cnt<<endl; 42 43 return 0; 44 }
直接计算结果,没有使用队列存数组,空间复杂度O(1)
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 5 using namespace std; 6 7 int main() { 8 int n; 9 cin >> n; 10 vector<int> a(n, 0); 11 for (int i = 0; i < n; ++i) 12 cin >> a[i]; 13 sort(a.begin(), a.end()); 14 int i = 0; 15 int j = n - 1; 16 int ret = abs(a[0] - a[n - 1]); 17 while (i <= n / 2 - 2) 18 ret += abs(a[i] - a[j - 1]) + abs(a[(i++) + 1] - a[(j--)]); 19 if (n % 2 == 1) 20 ret += max(abs(a[(n-1)/2-1]-a[(n-1)/2]),abs(a[(n-1)/2+1]-a[(n-1)/2])); 21 cout << ret << endl; 22 return 0; 23 }
10. 整数翻转(迅雷) 简单
示例1 输入 123 输出 321 示例2 输入 -123 输出 -321 示例3 输入 200 输出 2 备注: 输入的整数为32位整数
解题思路:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int n,res=0; 6 cin>>n; 7 8 while(n){ 9 res = res*10; 10 res +=n%10; 11 n = n/10; 12 } 13 14 cout<<res<<endl; 15 return 0; 16 }
11. 堆棋子(网易)
示例1 输入 4 1 2 4 9 1 1 1 1 输出 0 1 3 10
解题思路:
12. 小易喜欢的数列(网易)
示例1 输入 2 2 输出 3
解题思路:
13. 删除重复字符(爱奇艺)简单
输入 banana 输出 ban
解题思路:
用集合判断字符是否重复出现过
1 /*用判断字符串每个字符是属于('a' - 'z')*/ 2 #include<bits/stdc++.h> 3 using namespace std; 4 5 int main(){ 6 string str,res=""; 7 cin>>str; 8 unordered_set<char> cset; 9 int sz = str.size(); 10 for(int i=0;i<sz;i++){ 11 if(str[i]>'z' ||str[i]<'a'){ 12 cout<<"error string!"<<endl; 13 return 0; 14 } 15 16 if(cset.find(str[i])==cset.end()){//没有找到元素 17 res+=str[i]; 18 cset.insert(str[i]); 19 } 20 } 21 cout<<res<<endl; 22 return 0; 23 }
使用数组记录26个字符是否出现过
1 //建表 2 #include<iostream> 3 #include<string> 4 using namespace std; 5 int main() 6 { 7 string str; 8 int WordTable[26] = { 0 }; 9 while (cin >> str) 10 { 11 for (char c : str) 12 if (WordTable[c - 'a'] == 0) 13 WordTable[c - 'a'] = 1,cout<<c; 14 cout << endl; 15 } 16 return 0; 17 }
14. 循环数比较(爱奇艺)一般-较简单
输入 1010 3 101010 2 输出 Equal
解题思路:
使用字符串去比较,位数不同,谁位数多,谁大。
位数相同,用字符串比较去判断大小
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 string catStr(string str, int x){ 5 string res=""; 6 for(int i=0;i<x;i++){ 7 res +=str; 8 } 9 return res; 10 } 11 12 int main(){ 13 string x1,x2; 14 int k1,k2; 15 cin>>x1>>k1>>x2>>k2; 16 int sz1=x1.size(),sz2=x2.size(); 17 if(sz1*k1>sz2*k2) 18 cout<<"Greater"<<endl; 19 else if(sz1*k1<sz2*k2) 20 cout<<"Less"<<endl; 21 else{ //位数相同 22 x1 = catStr(x1, k1); 23 x2 = catStr(x2, k2); 24 if(x1>x2) 25 cout<<"Greater"<<endl; 26 else if(x1<x2) 27 cout<<"Less"<<endl; 28 else 29 cout<<"Equal"<<endl; 30 } 31 32 return 0; 33 }
15. 判断题(爱奇艺) 逻辑题-没看懂
输入 3 1 2 输出 2
解题思路:
1)逻辑题:max=n-abs(t-a)
1 //逻辑题得到max=n-abs(t-a) 2 #include <iostream> 3 using namespace std; 4 int main(void){ 5 int n, t, a; 6 cin >> n >> t >> a; 7 int res = n - abs(t - a); 8 cout << res << endl; 9 return 0; 10 }
1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int a,n,t; 6 cin>>n>>t>>a; 7 cout<<((t>a)?(a+n-t):(t+n-a))<<endl; 8 return 0; 9 }
2)min(n-t,n-a)+min(t,a)
1 #include<stdio.h> 2 int min(int a,int b){return a<b?a:b;} 3 int main(){ 4 int n,t,a; 5 scanf("%d%d%d",&n,&t,&a); 6 printf("%d",min(n-t,n-a)+min(t,a)); 7 }
16. 2的N次方(迅雷)
输入 512 输出 134078079299425970995740249982058461274793658205923933777
235614437217640300735469768018742981669034276900318581864
86050853753882811946569946433649006084096
解题思路:
17. 编程题1(字节调动)
输入 5 1 2 5 3 4 6 7 5 9 0 输出 4 6 7 5 9 0
解题思路:
18. 幂运算(滴滴出行)
输入 95.123 12 0.1 1 输出 548815620517731830194541.899025343415715973535967221869852721 0.1
解题思路:
19. 排序(爱奇艺)
输入 3 3 2 1 输出 2
解题思路:
20. 回文素数(爱奇艺)
输入 100 150 输出 2
解题思路: