当前位置:   article > 正文

美团 2023年春招 JAVA后端开发方向_小美希望两个人吃的部分的美味度之和尽可能接近,请你输出 s1- s2的最小值。 (其中

小美希望两个人吃的部分的美味度之和尽可能接近,请你输出 s1- s2的最小值。 (其中

分糖

  1. 时间限制:3000MS
  2. 内存限制: 589824KB
  3. 题目描述:
  4. 小美因乐于助人的突出表现获得了者师的嘉奖。
  5. 老师允许小美从一堆n个编号分别为1,2,..,n的糖果中选择任意多个糖果作为奖励(每种编号的果各一个),
  6. 但为了防止小美一次吃太多糖果有害身体健康,老师设定了个眼制:
  7. 如果选择了编号为i的果,那么就不能选择编号为 i-1,i-2,i+1,i+2的四个糖果了。
  8. 在小美看来,每个糖果都有一个对应的美味值,小美想让她选出的糖果的美味值之和最大!
  9. 作为小美的好朋友,请你帮帮她!

输入描述

  1. 第一行一个整数n,表示糖果数量。
  2. 第二行n个整数a1,a2,...,an,其中ai表示编号为i的糖果的美味值。
  3. 1<=n<=500001<=ai<=10000

输出描述

输出一行一个数,表示小美能获得的糖果美味值之和最大值。

样例输入

  1. 7
  2. 3 1 2 7 10 2 4

样例输出

14

思路:设定dfs(idx,sum),i表示当前考虑第i个糖果,sum表示当前美味值的和。

第一种情况:每个位置都可以不选,那么对应的下一个状态就是dfs(i+1,sum)。

第二种情况:当满足满足used[i-2] = used[i-1] =false时,那么就可以选当前糖果,即令used[i]=true,下一个状态为dfs(i+1,sum+a[i]),状态退出时置used[i]=false。

  1. #include<iostream>
  2. using namespace std;
  3. const int maxn = 5e4 + 7;
  4. int n, a[maxn], global_max;
  5. bool used[maxn];
  6. void DFS(int idx, int sum){
  7. if(idx == n){
  8. global_max = max(global_max, sum);
  9. return;
  10. }
  11. bool can_use = true;
  12. for(int i = max(idx - 2, 0); i < idx; ++ i){
  13. can_use &= (! used[i]);
  14. }
  15. if(can_use){
  16. used[idx] = true;
  17. DFS(idx + 1, sum + a[idx]);
  18. used[idx] = false;
  19. }
  20. DFS(idx + 1, sum);
  21. }
  22. int main(){
  23. cin >> n;
  24. int idx;
  25. for(idx = 0; idx < n; ++ idx){
  26. cin >> a[idx];
  27. }
  28. DFS(0, 0);
  29. cout << global_max;
  30. return 0;
  31. }

有一个剪枝优化的方法即,当我们考虑i号糖果时,如果剩下的所有糖果都考虑了(显然这不可能,因为并不满足当选择j时不选择j-1,j-2,j+1,j+2),但是如果剩下的都选了还不能大于当前得到的最大值,那很显然这种情况可以直接不考虑了,因为及时考虑了也不可能是答案。

  1. #include<iostream>
  2. using namespace std;
  3. const int maxn = 5e4 + 7;
  4. int n, a[maxn], rest[maxn], global_max; //rest[i] 除去0-i-1部分即i-n-1部分的和
  5. bool used[maxn];
  6. void DFS(int idx, int sum){
  7. if(sum + rest[idx] <= global_max){
  8. return;
  9. }
  10. if(idx == n){
  11. global_max = max(global_max, sum);
  12. return;
  13. }
  14. bool can_use = true;
  15. for(int i = max(idx - 2, 0); i < idx; ++ i){
  16. can_use &= (! used[i]);
  17. }
  18. if(can_use){
  19. used[idx] = true;
  20. DFS(idx + 1, sum + a[idx]);
  21. used[idx] = false;
  22. }
  23. DFS(idx + 1, sum);
  24. }
  25. int main(){
  26. cin >> n;
  27. int idx, prefix_sum = 0, sum = 0;
  28. for(idx = 0; idx < n; ++ idx){
  29. cin >> a[idx];
  30. sum += a[idx];
  31. }
  32. for(idx = 0; idx < n; ++ idx){
  33. rest[idx] = sum - prefix_sum;
  34. prefix_sum += a[idx];
  35. }
  36. DFS(0, 0);
  37. cout << global_max;
  38. return 0;
  39. }

春游

  1. 时间限制:3000MS
  2. 内存限制: 589824KB
  3. 题目描述:
  4. 小美因乐于助人的突出表现获得了者师的嘉奖。
  5. 老师允许小美从一堆n个编号分别为1,2,..,n的糖果中选择任意多个糖果作为奖励(每种编号的果各一个),
  6. 但为了防止小美一次吃太多糖果有害身体健康,老师设定了个眼制:
  7. 如果选择了编号为i的果,那么就不能选择编号为 i-1,i-2,i+1,i+2的四个糖果了。
  8. 在小美看来,每个糖果都有一个对应的美味值,小美想让她选出的糖果的美味值之和最大!
  9. 作为小美的好朋友,请你帮帮她!

输入描述

  1. 第一行两个整数n和m,表示小美的巧克力数量和小美的询问数量
  2. 第二行n个整数a1,a2,...,an,表示n块正方形巧克力板的边长。注意你不能将巧克力板进行拆分。
  3. 第三行m个整数q1,q2,...,qm,第i个整数qi表示询问: 如果小美选择多少块巧克力板?
  4. (不考虑体积影响,我们认为只要质量满足要求,巧克力板总能塞进包里)
  5. 1<=n,m<=50000,1<=ai<=10^4,1<=qi<=10^18

输出描述

输出一行m个整数,分别表示每次询问的答案

样例输入

  1. 5 5
  2. 1 2 2 4 5
  3. 1 3 7 9 15

样例输出

1 2 3 4 5

思路:我们先单看某一个查询qi,要想装最多的块数,不考虑体积只考虑体重,那么肯定尽量装重量小的巧克力才能装最多的块数。现在我们看多个查询,我们可以从小到大进行查询,因为一定会满足 大包能装的数量不会小于小包的,因此我们只需要在小包装的基础上,试着装更多块即可,即对查询做一次离线排序后,计算答案,再按照输入顺序排序回去输出答案。

  1. #include<iostream>
  2. #include<algorithm>
  3. using namespace std;
  4. const int max_num = 5e4 + 7;
  5. int a[max_num];
  6. struct Query{
  7. long long q_value;
  8. int ori_idx, answer;
  9. };
  10. Query queries[max_num];
  11. int main(){
  12. int n, m, idx, query_idx, a_idx;
  13. long long q_value;
  14. cin >> n >> m;
  15. for(a_idx = 1; a_idx <= n; ++ a_idx){
  16. cin >> a[a_idx];
  17. }
  18. for(query_idx = 1; query_idx <= m; ++ query_idx){
  19. cin >> q_value;
  20. queries[query_idx] = Query{q_value, query_idx, 0};
  21. }
  22. sort(queries, queries + m, [](Query A, Query B){
  23. return A.q_value < B.q_value;
  24. });
  25. q_value = 0;
  26. a_idx = 1;
  27. for(query_idx = 1; query_idx <= m; ++ query_idx){
  28. while(a_idx <= n - 1 && q_value + a[a_idx + 1] < queries[query_idx].q_value){
  29. q_value += a[a_idx ++];
  30. }
  31. queries[query_idx].answer = a_idx;
  32. }
  33. sort(queries, queries + m, [](Query A, Query B){
  34. return A.ori_idx < B.ori_idx;
  35. });
  36. for(query_idx = 1; query_idx <= m; ++ query_idx){
  37. cout << queries[query_idx].answer << " ";
  38. }
  39. return 0;
  40. }

当然,如果读者注意到本题数据描述上的条件,n<=50000,1<=ai<=10^4,1<=qi<=10^18,a的最大和为5*10^8,因此当查询大于这个界限值的时候,很显然所有的巧克力都能装下。

解释器

  1. 时间限制:3000MS
  2. 内存限制: 589824KB
  3. 题目描述:
  4. 小美因为自己差劲的表达能力而苦恼,小美想制作一个解释器,这样她可以在无法表达的情况下让解释器
  5. 帮她解释程序。好巧不巧小美翻开了编译原理的书,找到了解释器的制作方式,她决定先制作一个书上练
  6. 习题中描述的小解释器试试。小美需要诞入一行字符串,其格式为"key1=val1;key2=val2;...;
  7. keyn-1=valn-1;keyn =valn;"(不包含引号)。这样的n对key,value对,其中keyi和vali为第i对
  8. key,value对,且均为仅包含大小写英文字母、数字与斜杠的非空字符串。例如对于字符串
  9. "SHELL=/bin/bash;HOME=/home/xiaomei;LOGNAME=xiaomei;",那么其中包含三对keyvalue对,
  10. 以(keyvalue)形式展示分别为(SHELL,/bin/bash)、(HOME,/home/xiaomei)、(LOGNAME,xiaomei)。
  11. 接下来,小美的解释器需要接受q次询问,每次询问给出一个仅包含大小写英文字母、数字与斜杠的非空
  12. 字符串,如果存在某对key,value对的key值与之相同,那么输出对应的value; 如果存在多对key,value
  13. 对的key值与之相同,那么输出其中编号最大的,也即最后那一对的value值;如果一对也不存在,那么输出
  14. EMPTY。

输入猫述

  1. 第一行一个字符串S,满足题中所述格式。
  2. 接下来一个整数q,表示有q个询问。
  3. 接下来q行,每行一个仅包含大小写英文字母、数字与斜杆的非空字符串,分别为S1,S2,...,Sq
  4. 依次表示q次询问。
  5. 令|S|表示字符串S的长度。
  6. 1<=|S|<=500000<sum{|si|, i=[1,q]}<=|S|,1<=q<=300,S中至少包含一对key,value对

输出描述

输出q行,每行一个字符串表示答案

输入样例

  1. LOGNAME=default;SHELL=/bin/bash;HOME=/home/xiaomei;LOGNAME=xiaomei;
  2. 4
  3. SHELL
  4. HOME
  5. LOGNAME
  6. logname

输出样例

  1. /bin/bash
  2. /home/xiaomei
  3. xiaomei
  4. EMPTY

思路:本题最直观的想法就是对字符串进行分割,首先以';'分割出每一个key-value对,然后对每一个key-value对再以=分割得到key和value,再以哈希表存储。对于 如果存在多对key,value
对的key值与之相同,那么输出其中编号最大的,也即最后那一对的value值,其实不需要特殊考虑,因为在哈希表内,对同一个key的赋值,编号大的value一定会覆盖编号小的。

  1. #include<iostream>
  2. #include<string>
  3. #include<unordered_map>
  4. using namespace std;
  5. unordered_map<string, string> key_value;
  6. void add(string str){
  7. int i, n = str.length();
  8. for(i = 0; i < n; ++ i){
  9. if(str[i] == '='){
  10. string key = str.substr(0, i);
  11. string value = str.substr(i + 1, n - i);
  12. cout << key << ":" << value << endl;
  13. key_value[key] = value;
  14. break;
  15. }
  16. }
  17. }
  18. void analysis_str(string& str){
  19. int i, start = 0 , n = str.length();
  20. for(i = 0; i < n; ++ i){
  21. if(str[i] == ';'){
  22. add(str.substr(start, i - start));
  23. start = i + 1;
  24. }
  25. }
  26. if(start < n) add(str.substr(start, n - start));//处理一下如果输入末尾没有;的问题
  27. }
  28. int main(){
  29. string str, query;
  30. int q, i;
  31. cin >> str >> q;
  32. analysis_str(str);
  33. while(q --){
  34. cin >> query;
  35. cout << (key_value.find(query) == key_value.end() ? "EMPTY" : key_value[query]) << endl;
  36. }
  37. return 0;
  38. }

当然还有一个快一点的方法,先按照;再按照=划分总共会导致整个串遍历两次,考虑到输入的格式规范:key,value均为仅包含大小写英文字母、数字与斜杠的非空字符串,所以我们可以利用简单的状态机,初始状态为0,当状态为0时,遍历到的字符都是key的部分,而当遇到=时,状态切换到1,当状态为1时 ,遍历到的字符都是value的部分,而当遇到;时,表示已经遍历完了一个key-value对,此时状态切换为0。

  1. #include<iostream>
  2. #include<string>
  3. #include<unordered_map>
  4. using namespace std;
  5. unordered_map<string, string> key_value;
  6. int main(){
  7. string str, query, key;
  8. int q, i, start = 0, n;
  9. bool zero_state = false;
  10. cin >> str >> q;
  11. n = str.length();
  12. for(i = 0; i < n; ++ i){
  13. if(str[i] == '='){
  14. key = str.substr(start, i - start);
  15. start = i + 1;
  16. zero_state = false;
  17. }else if(str[i] == ';'){
  18. key_value[key] = str.substr(start, i - start);
  19. start = i + 1;
  20. zero_state = true;
  21. }
  22. }
  23. if(start < n) key_value[key] = str.substr(start, i - start);//处理一下如果输入末尾没有;的问题
  24. while(q --){
  25. cin >> query;
  26. cout << (key_value.find(query) == key_value.end() ? "EMPTY" : key_value[query]) << endl;
  27. }
  28. return 0;
  29. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/480719
推荐阅读
相关标签
  

闽ICP备14008679号