京东2018校招技术笔试编程题参考代码及思路
以下代码均来自几位大神的,不是我写的⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄ 大神们说不想露脸(✿◡‿◡)
在这里分享给大家~
回文
分析
暴力枚举一下check回文,可以确定出最后答案的一半,就可以得到答案了。
参考代码
#include <bits/stdc++.h> using namespace std; bool isPalindrome(string s) { int i = 0, j = s.size() - 1; while(i < j) if(s[i++] != s[j--]) return false; return true; } string s; int main() { cin >> s; string add; int i, j; for(i = 0; i < s.size(); i++) { if(isPalindrome(s.substr(i))) break; } for(int j = i - 1; j >= 0; j--) add += s[j]; s += add; cout << s.size() << endl; }
两个子串
分析
暴力枚举计算字符串前缀后缀相等的最长长度,然后拼接一下就是结果。
参考代码
#include <bits/stdc++.h> using namespace std; string s; int main() { cin >> s; int l = s.size(), m = 0; for(int i = 1; i < l; i++) { if(s.substr(0, i) == s.substr(l - i, i)) m = i; } cout << s.substr(0, l - m) + s << endl; return 0; }
括号匹配方案
分析
这个题字符串长度不长,可以直接爆搜。
有一种代码比较简单的解法,挨着累计'('的个数,遇到')'就完成一次匹配,把情况数乘进答案。本质是把题目所说的移除操作做了一个等价的变化。
参考代码
#include <bits/stdc++.h> using namespace std; string s; int main() { cin >> s; int ans = 1, cnt = 0; for(int i = 0; i < s.size(); i++) { if(s[i] == '(') { cnt++; } else { ans *= cnt; cnt--; } } cout << ans << endl; }
疯狂的序列
分析
范围比较大,考虑二分答案,等差数列求和来check。
参考代码
#include <bits/stdc++.h> using namespace std; long long n; int main() { cin >> n; long long l = 1, r = 2000000000LL, mid; while(l < r) { mid = (l + r) / 2; if(mid * (mid + 1) / 2 >= n) r = mid; else l = mid + 1; } cout << l << endl; return 0; }
神奇数
分析
注意到r - l不会特别大,直接枚举范围内的数,然后暴力check。
暴力check的时候注意到所有数位和最大只有81,所以会比较快。
参考代码
#include <bits/stdc++.h> using namespace std; bool check(int n) { char s[11]; int cur = 0, t = 0; while(n > 0) { s[cur] = n % 10; t += s[cur++]; n /= 10; } if(t % 2) return false; t /= 2; bool ok[42] = {0}; ok[s[0]] = true; for(int i = 1; i < cur; i++) { int v = s[i]; for(int j = 41; j >= 0; j--) { if(ok[j] && j + v <= 41) { ok[j + v] = true; } } if(ok[t]) { return true; } } return false; } int l, r; int main() { int res = 0; cin >> l >> r; for(int i = l; i <= r; i++) { if(check(i)) res++; } cout << res << endl; return 0; }
import java.util.HashSet; import java.util.Scanner; import java.util.Set; public class Main { public static boolean check(int n){ int[] s = new int[11]; int cur = 0, t = 0; while(n > 0) { s[cur] = n % 10; t += s[cur++]; n /= 10; } if( t % 2 == 1 ) return false; t /= 2; boolean[] ok = new boolean[42]; ok[s[0]] = true; for(int i = 1; i < cur; i++) { int v = s[i]; for(int j = 41; j >= 0; j--) { if(ok[j] && j + v <= 41) { ok[j + v] = true; } } if(ok[t]) { return true; } } return false; } public static int max(int a, int b){ return (a>b) ? a : b; } public static void main(String[] args) { Scanner in = new Scanner(System.in); int res = 0; int l = in.nextInt(); int r = in.nextInt(); for(int i = l; i <= r; i++) { if(check(i)) res++; } System.out.println(res); } }
求幂
分析
裸暴力好像只能拿20%的分
我们考虑去枚举n范围内的所有i,然后处理出i的幂那些数。
考虑对于i ^ x, 我们需要计算满足 (i ^ x) ^ c = (i ^ y) ^ d的数量,其中i ^ x, i ^ y <= n. 这些我们可以通过预处理出来。
然后对于(i ^ x) ^ c = (i ^ y) ^ d 其实意味着x c = y d, 意味着(x / y) = (d / c), 其中x, y我们可以在预处理之后枚举出来,于是我们就可以借此计算出n范围内有多少不同这种c和d去满足等式。
其实就等于 n / max(x / gcd(x, y), y / gcd(x, y)),然后都累加进答案。gcd()表示最大公约数。
中间可能产生重复枚举,我们用一个set或者hash容器标记一下就好。
以上枚举对于2~sqrt(n)。最后对于大于sqrt(n)的部分,每个的贡献都是n。
参考代码
#include <bits/stdc++.h> using namespace std; const int mod = 1e9 + 7; set<int> S; int n; int main() { cin >> n; long long res = 1LL * n * n % mod; for(int i = 2; i * i <= n; i++) { if(S.find(i) != S.end()) continue; long long tmp = i; int cnt = 0; while(tmp <= n) { S.insert(tmp); tmp = tmp * i; cnt++; } for(int x = 1; x <= cnt; x++) { for(int y = 1; y <= cnt; y++) { int g = __gcd(x, y); int tmpx = x / g; int tmpy = y / g; res = (res + n / max(tmpx, tmpy)) % mod; } } } res += 1LL * (n - S.size() - 1) * n; res %= mod; cout << res << endl; }
import java.util.HashSet; import java.util.Scanner; import java.util.Set; public class Main { public final static long MOD = 1000000000 + 7; public static int max(int a, int b){ return (a>b) ? a : b; } public static long gcd(long a,long b){ return (a % b == 0) ? b : gcd(b,a%b); } public static void main(String[] args) { Scanner in = new Scanner(System.in); long n = in.nextInt(); long ans = (long)1*n*(n*2-1) % MOD; Set<Integer> set = new HashSet<>(); for (int i = 2; i*i <= n; i++){ if ( set.contains(i)) continue; long tmp = i; int cnt = 0; while(tmp <= n) { set.add((int)tmp); tmp = tmp * i; cnt++; } for(int k = 1; k <= cnt; k++) { for(int j = k + 1; j <= cnt; j++) { ans = (ans + n / (j / gcd(k, j) ) * (long)2 ) % MOD; } } } System.out.println(ans); } }
前端
购物车
function add(items) { var tbody = document.getElementById('jsTrolley').getElementsByTagName('tbody')[0]; (items || []).forEach(function (item) { var tr = document.createElement('tr'); tr.innerHTML = '<td>' + item.name + '</td><td>' + item.price.toFixed(2) + '</td><td><a href="javascript:void(0);">删除</a></td>'; tbody.appendChild(tr); }); update(); } function bind() { var table = document.getElementById('jsTrolley'); table.addEventListener('click', function (event) { var el = event.target; if (el.tagName.toLowerCase() === 'a') { tr = el.parentNode.parentNode; tr.parentNode.removeChild(tr); update(); } }); } function update() { var table = document.getElementById('jsTrolley'); var tbody = table.getElementsByTagName('tbody')[0]; var tfoot = table.getElementsByTagName('tfoot')[0]; var tr = [].slice.call(tbody.getElementsByTagName('tr'), 0); var total = 0; tr.forEach(function (tr) { total += +(tr.getElementsByTagName('td')[1].innerHTML.trim()); }); tfoot.getElementsByTagName('td')[0].innerHTML = total.toFixed(2) + '(' + tr.length + '件商品)'; }