题目描述 - shopee的办公室(二)
shopee的办公室非常大,小虾同学的位置坐落在右上角,而大门却在左下角,可以把所有位置抽象为一个网格(门口的坐标为0,0),小虾同学很聪明,每次只向上,或者向右走,因为这样最容易接近目的地,但是小虾同学不想让自己的boss们看到自己经常在他们面前出没,或者迟到被发现。他决定研究一下如果他不通过boss们的位置,他可以有多少种走法?
输入描述:
第一行 x,y,n (0<x<=30, 0<y<=30, 0<=n<= 20) 表示x,y小虾的座位坐标,n 表示boss的数量( n <= 20)
接下来有n行, 表示boss们的坐标(0<xi<= x, 0<yi<=y,不会和小虾位置重合)
x1, y1
x2, y2
……
xn, yn
输出描述:
输出小虾有多少种走法
输入例子1:
3 3 2
1 1
2 2
输出例子1:
4
解法:
x, y, n = map(int, input().split())
M = [[1 for j in range(y + 1)]for i in range(x + 1)]
for i in range(n):
a, b = map(int, input().split())
M[a][b] = 0
def Enumerate(M, x, y):
for i in range(1, x + 1):
for j in range(1, y + 1):
if M[i][j] == 0: continue
M[i][j] = M[i-1][j] + M[i][j - 1]
return M[x][y]
print(Enumerate(M, x, y))
题目描述 - 实现字通配符*
在Linux Shell命令下通配符’‘表示0个或多个字符, 现编写一段代码实现通配符’‘的功能,注意只需要实现’*’, 不用实现其他通配符。
输入描述:
第一行输入通配字符串
第二行输入要匹配查找的字符串
输出描述:
输出所有匹配的字串起始位置和长度,每行一个匹配输出
如果不匹配,则输出 -1 0
如果有多个按照起始位置和长度的正序输出。
示例1
输入
shopee*.com
shopeemobile.com
输出
0 16
说明
0 起始位置,16长度
示例2
输入
*.com
shopeemobile.com
输出
0 16
1 15
2 14
3 13
4 12
5 11
6 10
7 9
8 8
9 7
10 6
11 5
12 4
示例3
输入
o*m
shopeemobile.com
输出
2 5
2 14
7 9
14 2
解法:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
using namespace std;
void match(set<pair<int, int>>& ans, string& pattern, string& target, int pat_cur_pos, int tar_cur_pos, int start)
{
if(pat_cur_pos==(int)pattern.size())
{
ans.insert({start, tar_cur_pos});
return;
}
if(tar_cur_pos==(int)target.size()) return;
if(pattern[pat_cur_pos]=='*')
{
match(ans, pattern, target, pat_cur_pos+1, tar_cur_pos+1, start);
match(ans, pattern, target, pat_cur_pos, tar_cur_pos+1, start);
match(ans, pattern, target, pat_cur_pos+1, tar_cur_pos, start);
}
else
{
if(pattern[pat_cur_pos]==target[tar_cur_pos])
{
match(ans, pattern, target, pat_cur_pos+1, tar_cur_pos+1, start);
}
}
}
int main()
{
set<pair<int, int>> ans;
string pattern, target;
cin >> pattern >> target;
for(int i=0;i<(int)target.size();i++)
{
match(ans, pattern, target, 0, i, i);
}
if(!(int)ans.size())
{
cout << "-1 0" <<endl;
}
else
{
for(auto x: ans)
{
if(!(x.second-x.first)) continue;
cout << x.first << " " << x.second - x.first << endl;
}
}
return 0;
}
题目描述 - Shopee的Orange Day
Shopee每个月都有属于大家的节日,每到这个时候,大家都会穿着橙色的T恤,吃着水果蛋糕,做着游戏。瞧,今天又是Orange Day了,吃货小虾同学早早的来到现场,看看有没有什么吃的,刚刚走进去就发现我们的前台mm愁眉苦脸的看着挂满礼物的发财树,细看发现,发财树的树枝因为承重不均,东倒西歪。是时候展现真正的技术啦,小虾同学,马上走上去,让前台mm把挂礼物的方案拿出来,前台mm拿出一大叠方案,小虾同学顿时傻眼了,但是他马上想到了一个方法,写一个程序判断每种方案的承重误差,把不合格的都干掉就行了。经过分析,把发财树抽象为一颗树。只要发财树的从顶部到各个叶子的各个路径上面的最大最小重量的差值在方案的误差范围内,就可以正常承重。
每个样例输入如下
输入的第一行输入 n,(2 ≤ n ≤ 100000,节点的编号为0到n-1,0为根节点)组成,
第二行有 n 个数,表示每个节点挂的礼物的重量 w(1<= w<= 1000)
下面是n-1行,每行有两个整数,第一个数表示父节点的编号,第二个数表示子节点的编号
输出最大差值。
解法:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <limits>
using namespace std;
struct TreeNode{
int data;
vector<int> childs;
TreeNode(){data = -1;}
};
TreeNode tree[100000];
vector<int> tmp_diff;
vector<int> tmp_stack;
int mmax, mmin;
void dfs(int indx)
{
tmp_stack.push_back(indx);
if(tree[indx].childs.size()==0)
{
mmax = INT_MIN;
mmin = INT_MAX;
for(int i=0;i<tmp_stack.size();i++)
{
int tmp_indx = tmp_stack[i];
mmax = max(mmax, tree[tmp_indx].data);
mmin = min(mmin, tree[tmp_indx].data);
}
tmp_diff.push_back(mmax-mmin);
}
else
{
for(int i=0;i<tree[indx].childs.size();i++)
{
dfs(tree[indx].childs[i]);
}
}
tmp_stack.pop_back();
}
int main()
{
int n;
cin >> n;
int data;
for(int i=0;i<n;i++)
{
cin >> data;
tree[i].data = data;
}
int father, child;
for(int i=0;i<n-1;i++)
{
cin >> father >> child;
tree[father].childs.push_back(child);
}
dfs(0);
int res = INT_MIN;
for(int i=0;i<tmp_diff.size();i++)
{
res = max(res, tmp_diff[i]);
}
cout << res << endl;
return 0;
}