360笔试编程交流(第二题没A,求解)

感觉今晚360的笔试很迷...为啥Java还有C++的问题...只能XJBC...然后编程题怒卡第二题...
人比较蠢,实在没想到Case是什么...遂放弃,怒交卷...其实是因为太饿吃饭去了...
(提前40mins交卷,答题时间 1:20mins 左右)
下面三道编程题的做法...欢迎交流...

第一题:算正方形面积
没啥好说的...题目限制的太死了...基本没啥意外情况需要考虑,排序求最大就行。结果记得用 long 就行,题目数据给的是 1e9,防范越界即可。

第二题:看花
用的前缀统计...卡在了一个case死活过不去...感觉非常难受...
做法是用 int[] 统计 i 时刻看到的花的种类。然后Q的时候利用 type[right] - type[left -1] 即可...
但是没 A 求大佬帮忙分析一下。
============================================================================
感谢评论区各位大佬的建议,已经找到前缀统计问题所在了。
反例为:1 2 2 2 2 2 2 3 3 3。 如果统计区间落在 [3, 5] 那么结果就是 0.
同时也有不少人反应说超时的问题,确实根据题目的数据量,如果直接 O(n) 统计是会超时的。
不过也有些人过了...应该是数据规模没卡到位吧...
正确的做法应该是使用 BIT 或者 Segment Tree 来做,这样可以保证在 O(logn) 的时间内完成统计。
应该也是出题人的本意。所以啊...有事没事不要偷懒,觉得可以偷过去...不然就会跟我一样...
============================================================================

看到有挺多人反馈第三题的...这题统一回复一下,用的是 LIS
第三题:求满足条件的最长子序列
想法比较简单,假设A中 X 在 Y 前面,那么B中肯定是反过来的。即是一个逆序。
因此可以直接把B反过来,求数组A和B的 LCS。
但是发现题目给的数据量 N = 50000.直接用普通的 LCS DP 解法肯定超时。
所以改成 LIS 的做法来做。虽然存在退化问题,但是Case里面明显没有包含这个情况。
因为数组中全是 1~n 的元素,并且不重复。所以题目冥冥之***就是在诱导你这么做...
(不过这个诱导是真的...不想过多吐槽...)代码写起来比字符串的快不少就是了。


#内推##笔试题目##求面经##360公司#
全部评论
想问下楼主,第三题,这么用LIS处理,还是没明白,可以的话,给贴个代码
点赞 回复 分享
发布于 2018-08-28 10:43
献上我一次性AC的代码,第二题看花的题目 public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { int n = scanner.nextInt(); int m = scanner.nextInt(); int[] watch = new int[n+1]; int i = 1; while (i < n+1) { watch[i++] = scanner.nextInt(); } int q = scanner.nextInt(); i = 0; int[][] questions = new int[q][2]; while (i < q) { questions[i][0] = scanner.nextInt(); questions[i][1] = scanner.nextInt(); i++; } processData(watch, questions, n); } } public static void processData(int[] watch, int[][] ques, int n) { Set<Integer> flours = null; for (int i = 0; i < ques.length; i++) { int start = ques[i][0]; int end = ques[i][1]; if (start < 1) start = 1; if (end > n) end = n; flours = new HashSet<>(); while (start <= end) { flours.add(watch[start++]); } System.out.println(flours.size()); } }
点赞 回复 分享
发布于 2018-08-28 10:05
第二题看数据量直接暴力就可以过啊2000×2000的预处理
点赞 回复 分享
发布于 2018-08-28 08:29
 #include <iostream>  #include <vector>  #include <algorithm>  using namespace std;  bool is_had(vector<int> v, size_t i, size_t j) {     for (size_t m = i; m < j; ++m) {        if (v[m] == v[j])         return true;      }      return false;  }  int dp[2000][2000] = { 0 };  int main()   {      int n = 0;      int m = 0;      cin >> n >> m;      vector<int> v;      int tmp = 0;      for (size_t i = 0; i < n; ++i) {          cin >> tmp;          v.push_back(tmp);      }      size_t q = 0;      cin >> q;      vector<vector<int> >res;      int tmp2;      for (size_t i = 0; i < q; ++i) {          vector<int> t;          cin >> tmp >> tmp2;          t.push_back(tmp);          t.push_back(tmp2);          res.push_back(t);      }      for (size_t i = 0; i < n; ++i)          dp[i][i] = 1;      for (size_t i = 0; i < n; ++i) {          for (size_t j = i + 1; j < n; ++j) {              if (is_had(v, i, j))                  dp[i][j] = dp[i][j - 1];              else                  dp[i][j] = dp[i][j - 1] + 1;          }      }      for (size_t i = 0; i < q; ++i) {          cout << dp[res[i][0] - 1][res[i][1] - 1] << endl;      }      return 0;  } 有什么问题啊。。。。求告知
点赞 回复 分享
发布于 2018-08-27 22:24
第二题一开始和老哥想的一样,只过了29%,然后发现这是个假算法。。。 比如 4 3 1 2 2 2 3 1 3 3 按照这个思路得到的结果是 0,但是答案显然是 1 所以。。还是直接暴力吧。。 我选择题花太长时间了,然后第三题。。刚写了个 lcs 还没来得及交就到时间了。。 心酸。。
点赞 回复 分享
发布于 2018-08-27 22:02
第二题不要用***树麽。。。
点赞 回复 分享
发布于 2018-08-27 21:57
第二题set去重直接A了 public class Main2 { private static Scanner sc = new Scanner(System.in); public static void main(String[] args) { String[] str1 = sc.nextLine().split(" "); int n = Integer.valueOf(str1[0]); int m = Integer.valueOf(str1[1]); String[] str2 = sc.nextLine().split(" "); int[] arrA = new int[n]; for(int i = 0; i < n; ++i) { arrA[i] = Integer.valueOf(str2[i]); } int Q = Integer.valueOf(sc.nextLine().split(" ")[0]); for(int i = 0; i< Q; ++i) { int l = sc.nextInt(); int r = sc.nextInt(); Set<Integer> set = new HashSet<>(); for(int j = l - 1; j < r; j++) { set.add(arrA[j]); } System.out.println(set.size()); } } }
点赞 回复 分享
发布于 2018-08-27 21:56
哪里错了,提示是超时 int main() {     int n, m, q;     int count = 0;     set<int> s;     cin >> n >> m;     vector<int> vec;     for (int i = 0; i<n; ++i) {         int k = 0;         cin >> k;         if (s.count(k) == 0) {             s.insert(k);             ++count;         }         vec.push_back(count);     }     cin >> q;     for (int i = 0; i<q; ++i) {         int t1, t2;         cin >> t1 >> t2;         int res = 1 + vec[t2 - 1] - vec[t1 - 1];         cout << res << endl;     }     return 0; }
点赞 回复 分享
发布于 2018-08-27 21:50
开始我一直86,但是如果花的种数是1的话可以直接输出1了。然后a了
点赞 回复 分享
发布于 2018-08-27 21:49
第二题要考虑left和right中间,包含left左边的情况,去重可以a,但是感觉不对。
点赞 回复 分享
发布于 2018-08-27 21:47
第二题用Set去重就A了啊
点赞 回复 分享
发布于 2018-08-27 21:40
大佬,你可能把第二题想复杂了,就是个区间内不重复的值有几个的问题。map去重即可。
点赞 回复 分享
发布于 2018-08-27 21:39
cin cout 改成 C 语言的输入输出。
点赞 回复 分享
发布于 2018-08-27 21:36
第3题 是公共子串 还是最长公共子序列? 求具体解释~
点赞 回复 分享
发布于 2018-08-27 21:36
一样的第二个方法,没有A
点赞 回复 分享
发布于 2018-08-27 21:33

相关推荐

喜欢飞来飞去的雪碧在刷代码:可以试一试字节
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务