1.商汤的一道填空题(我觉得可以改成编程题做)
#include <iostream>
using namespace std;
int count = 0;
void Perm(int a[], int k, int m) //Perm函数用来解决排列问题
{
int i;
if(k == m)
{
if(a[5] > a[0] && a[6] > a[1])
{
if(a[7] > a[2] && a[8] > a[3] && a[9] > a[4])
{
if(a[4] > a[3] && a[3] > a[2] && a[2] > a[1] && a[1] > a[0])
{
if(a[9] > a[8] && a[8] > a[7] && a[7] > a[6] && a[6] > a[5])
{
for(i = 0; i <= 4; i++)
cout << "[" <<a[i] << "]";
cout <<endl;
for(i = 5; i <= 9; i++)
cout << "[" << a[i] << "]";
cout <<endl;
cout << "-----------------" <<endl;
count++;
}
}
}
}
}
else
for(int i = k; i <= m; i++)
{
swap(a[k],a[i]);
Perm(a, k+1, m);
swap(a[k], a[i]);
}
}
template <class T>
void swap(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
int main()
{
int a[10] = {5,4,3,2,1,6,7,8,9,10};
Perm(a, 0, 9);
cout << "Count:" << count <<endl;
return 0;
}
这题要是会排列算法解题就会轻松很多,之后就是在排列算法中加入限制条件即可。
2.百词斩
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
int Asd(char *p, char *q, int sumlen, int len, int n)
{ //*p指向数组,*q指向字符串
int i,j,flag,k = 0; //sumlen是数组的长度,len是输入字符串的长度,n是列
for(j = 0; j < len; j++)
{
flag = 0;
for(i = 0; i < sumlen; i++)
{
if(p[i] == q[j] && j == 0)
{
flag = 1; //flag
}
if(p[i] == q[j] && (p[i-1] == q[j-1] || p[i+1] == q[j-1] || p[i-n] == q[j-1] || p[i+n] == q[j-1]))
{
flag = 1;
if(flag == 1 && j == len-1)
{
return 1;
}
}
}
if(flag == 0)
{
break;
return 0;
}
}
}
int main()
{
int i = 0,m,n,sum;
char *p;
char a;
string s1;
cin >> m >> n;
sum = m*n;
p = new char[sum]; //常规操作,创建数组
int j = sum;
while(j > 0) //输入
{
cin >> a;
if(a >= 'A' && a <= 'Z' || a >= 'a' && a <= 'z')
{
p[i++] = a;
j--;
}
}
cin >> s1;
int strlength = s1.length();
const char *r = s1.data();
char *q = const_cast<char*>(r); //string转char*
int reasult = Asd(p, q, sum, strlength, n);
if(reasult == 1)
cout << "true" <<endl;
else
cout << "false" <<endl;
return 0;
}
读懂题就好,整体不难。其中有一段代码时string转const char*的,可以不用那么做,我这样写也只是想用以下data()函数而已。
3.thoughtworks的作业
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
void Change(char *mat, int *asd, int q, int w);
void Display(char *mat, int x, int m)
{
int i;
for(i = 0; i < x; i++)
{
if(i%(2*m+1) == 0 && i > 0)
cout <<endl;
cout << "[" << mat[i] << "]" << " ";
}
}
void Initall(char *mat, int x)
{
int i;
for(i = 0; i < x; i++)//初始化墙
{
mat[i] = 'W';
}
}
void Init(char *mat, int n, int m)
{
int i,j,k;
for(i = 1; i < 2*n+1; i = i+2)
{
for(j = 1; j < 2*m+1; j = j+2)
{
*(mat + i*(2*m+1) + j) = 'R';
}
}
}
void Input(char *mat, int q, int w)
{
char str[100] = "0,1 0,2;1,0 1,1;1,2 1,1;2,1 2,0;0,0 1,0;0,2 1,2;1,1 2,1;1,2 2,2;0,1 1,1";
char *p1 = str;
char *p2, *p3, *p4;
int asd[4] = {0};
int a,x,y,length,k = 0,i = 0;
printf("%s\n", str);
int len = strlen(str);
p2 = strtok(p1, ";");
while((len > 0) && (p2 = strtok(p1, ";")) != (char *)NULL)
{
p1 += strlen(p2) +1;
len -= strlen(p2) +1;
length = strlen(p2)+1;
while(length > 0 && (p3 = strtok(p2, " ")) != (char *)NULL)
{
p2 += strlen(p3) + 1;
length -= strlen(p3) + 1;
if (i == 4)
i = 0;
if (k == 4)
k = 0;
while((p4 = strtok(p3, ",")) != (char *)NULL)
{
a = atoi(p4);
asd[i++] = a;
p3 = (char *)NULL;
k++;
if (i == 4 && k == 4)//判断什么时候传数据
{
Change(mat, asd, q, w);
}
}
}
}
}
void Change(char *mat, int *asd, int q, int w)
{
int a,b,x,y;
int m,n;
a = asd[0];
b = asd[1];
x = asd[2];
y = asd[3];
if(a == x || b == y)//此时是上下左右的关系
{
if(a == x)//行相等
{
m = 2*a+1;
if(b < y)
n = 2*b+2; //n是转换后的列
else
n = 2*y+2;
*(mat + (m*(2*w+1)) + n) = 'R';
}
else//列相等
{
n = 2*b+1;
if(a < y)
m = 2*(a)+2;
else
m = 2*(y)+2;
*(mat + (m*(2*w+1)) + n) = 'R';
}
}
else
{
cout << "Maze format error!" <<endl;
}
}
int main()
{
int n,m;//n是行,m是列
char *p;
cout << "输入行列数:";
cin >> n >> m;
int x = (2*n+1)*(2*m+1);
p = new char[x];
Initall(p, x);
cout << "Output:" <<endl;
Init(p, n, m);
Input(p, n, m);
Display(p, x, m);
cout <<endl;
return 0;
}
这是测试代码,只要把输入修改以下就可以了,难点就是字符串的分割(不要在意代码量和时间、空间复杂度,做出来就没有心思优化了)。
4.京东(开发&测试都有)
#include <iostream>
#include <vector>
#include <algorithm>
#define N 20000
using namespace std;
int n_temp[N], temp_to[N], f_temp[N], res, temp_v;
int x[N], y[N];
int tot = 0, po, mtemp;
void fundfs(int u, int bu, int dis, int index_x, int index_y)
{
if (dis>mtemp) { mtemp = dis; po = u; }
for (int e = f_temp[u]; e; e = n_temp[e])
{
temp_v = temp_to[e];
if (temp_v != bu && (!((u == index_x && temp_v == index_y) || (u == index_y && temp_v == index_x))))
{
fundfs(temp_v, u, dis + 1, index_x, index_y);
}
}
}
void funcreate(int a, int b)
{
tot++;
n_temp[tot] = f_temp[a];
f_temp[a] = tot;
temp_to[tot] = b;
}
int main()
{
int n;
cin >> n;
for (int i = 0; i<n - 1; ++i)
{
cin >> x[i] >> y[i];
funcreate(x[i], y[i]);
funcreate(y[i], x[i]);
}
for (int i = 0; i<n - 1; ++i)
{
mtemp = 0; po = 0;
fundfs(x[i], 0, 0, x[i], y[i]);
fundfs(po, 0, 0, x[i], y[i]);
int tmp = mtemp; mtemp = 0; po = 0;
fundfs(y[i], 0, 0, x[i], y[i]);
fundfs(po, 0, 0, x[i], y[i]);
if (tmp*mtemp>res) res = tmp*mtemp;
}
cout << res << endl;
return 0;
}
网上大牛写的代码,我还在看。
5.美团(后台开发)
小明拿到一个数列a1,a2,…an,小明想知道存在多少个区间[l,r]同时满足下列两个条件:
(1)r - l + 1 = k;
(2)在al,al+1,…ar中存在一个数至少出现t次
输出满足条件的区间个数。
输入:
输入一行三个整数:n,k,t(1<=n,k,t<=10^5)
第二行n个整数:a1,a2,…an(1<=ai<=10^5)
样例输入:
5 3 2
3 1 1 1 2
样例输出:
3
Hint
区间[1,3]中1出现了2次,区间[2,4]中1出现了3次,区间[3,5]中1出现了2次,使用一共有3个区间满足条件
牛客网WAK的思路:
先判断n和k的关系,若k>n,直接返回0,若k<n,再进行后续计算
设置一维数组lst[10005],保存数列中值出现次数
设置count,保存ar-al中出现t次及以上数的个数
设置num,保存区间数
首先从0到n-k-1遍历一遍,对lst、count、num进行初始化
然后将窗口向右滑动,每次从头去一个,从尾部添加一个,动态维护lst、count、num的值,最后输出num的值即可
#include<bits/stdc++.h>
using namespace std;
int lst[10005];
int main(){
int n,k,t;
while(cin>>n>>k>>t)
{
if(k<=n)
{
vector<int> vec;
memset(lst,0,sizeof(lst));
for(int i = 0;i<n;i++)
{
int x;
cin>>x;
vec.push_back(x);
}
int count = 0;
int num = 0;
for(int i = 0;i<k;i++)
{
lst[vec[i]]++;
if(lst[vec[i]]==t)
count++;
}
if(count>0)
num++;
for(int i = 0;i<n-k;i++)
{
lst[vec[i]]--;
if(lst[vec[i]]==t-1)
count--;
lst[vec[i+k]]++;
if(lst[vec[i+k]]==t)
count++;
if(count>0)
num++;
}
cout<<num<<endl;
}//if(k<=n)
else
cout<<0<<endl;
}
return 0;
}
6.美团(后台开发)
给定一张包含N个点、N-1条边的无向连通图,节点从1到N编号,每条边的长度均为1。假设你从1号节点出发并打算遍历所有节点,那么总路程至少是多少?
输入
第一行包含一个整数N,1≤N≤100000。
接下来N-1行,每行包含两个整数X和Y,表示X号节点和Y号节点之间有一条边,1≤X,Y≤N。
输出
输出总路程的最小值。
牛客网WAK的思路:走完所有节点类似于深度优先搜索,也就是说除了最后一条路径外,别的路径都经历了正着走,再返回
的过程,也就是两遍,设最后一条路径为x,总分支数为n-1,总路径=2*(n-1-x)+x=2*n-2-x,当x最大时,总路径最小,所以转化为求多叉树的深度。
输入: 输入:
6 6
1 3 1 2
3 6 1 3
6 4 1 5
4 5 1 4
5 2 4 6
输出:5 输出:8
#include<bits/stdc++.h>
using namespace std;
int lst[100005];
int main(){
int n;
while(cin>>n)
{
memset(lst,0,sizeof(lst));
for(int i = 0;i<n-1;i++)
{
int a,b;
cin>>a>>b;
lst[b] = lst[a]+1;//当前节点的深度
}
int depth = 0;
for(int i = 1;i<=n;i++)
depth = lst[i]>depth?lst[i]:depth;//找到最大值
cout<<2*n-2-depth<<endl;
}
return 0;
}
(先整理这么多吧,持续更新中)