编程题题解大全

2016奇虎360研发工程师内推笔试编程题 - 题解

FlushHip - http://blog.csdn.net/flushhip

讲道理,这套题目很水,不适合练手......,但还是日常写一下报告吧,题目链接:点这里.

第一题

解析:

找一个字符串中第一次只出现一次的字母.这不瞎搞吗,直接用$hash$或$map$搞一下就可以了.

代码:

#include <bits/stdc++.h>

using namespace std;

#define MAX_BUF 1000005

char str[MAX_BUF];

int main()
{
    int n;
    for (scanf("%d", &n); n--;) {
        scanf("%s", str);
        map<char, int> mp;
        for (int i = 0; str[i]; i++)
            mp[str[i]]++;
        for (int i = 0; str[i]; i++) {
            if (mp[str[i]] == 1) {
                cout << str[i] << endl;
                break;
            }
        }
    }
    return 0;
}

第二题

解析:

找镇长,要求是:所有人都认识他,他不认识所有人,还问我们可以找到几个这样的候选镇长.很无语,这明显最多只能找到一个好吧,直接开数组存下他认识多少人,被多少人认识就好了.

代码:

#include <bits/stdc++.h>

using namespace std;

#define MAX_BUF 100005



int main()
{
    int T;
    for (scanf("%d", &T); T--;) {
        int n, m;
        scanf("%d%d", &n, &m);
        int *in = new int[n + 1], *out = new int[n + 1];
        for (int i = 0; i < n + 1; i++)
            in[i] = out[i] = 1;

        while (m--) {
            int x, y;
            scanf("%d%d", &x, &y);
            if (x == y)
                continue;
            in[y]++;
            out[x]++;
        }

        vector<int> ans;
        for (int i = 1; i <= n; i++)
            if (in[i] == n && out[i] == 1)
                ans.push_back(i);
        if (0 == ans.size())
            cout << 0 << endl <<endl;
        else {
            cout << ans.size() << endl;
            for (int i = 0; i < (int)ans.size(); i++)
                cout << ans[i] << (i == (int)ans.size() - 1 ? "\n" : " ");
        }

        delete[] in;
        delete[] out;
    }
    return 0;
}
#C++工程师##算法工程师#
全部评论
去哪儿2017校园招聘 开发工程师(第一批次)- 题解 FlushHip - http://blog.csdn.net/flushhip 题目链接:点这里. 这套题目有点味道啊,不算难,但是考验编码技巧,尤其是最后一题,我也是醉了,看人家用Python的,直接调用库函数,几行代码就搞定了,看来Python大法还是牛啊,C++写了好长的代码. 第一题 题目:联通图形 给你一个图片,如图 ,然后再给你一串字符,问你这些字符在图上是不是连通的. 解析: 遍历每个字符,看看当前字符是否和整个字符中的某一个字符相邻,如果每个字符都和某个字符相邻,那么就是连通的. 代码: #include <bits/stdc++.h> using namespace std; int getNum(char c) { if (isdigit(c)) return c - '0'; return c - 'a' + 10; } int main() { while (true) { string strs; while (true) { char c, d; if (EOF == scanf("%c%c", &c, &d)) goto F; strs.push_back(c); if (d == '\n') break; } if (strs.size() == 1) { cout << "pong" << endl; continue; } bool verify = true; for (int i = 0; i < strs.size(); i++) { int tag = getNum(strs[i]); bool isOk = false; for (int j = 0; j < strs.size(); j++) { if (i == j) continue; int v = getNum(strs[j]); if (tag - v == 1 || v - tag == 1 || tag - v == 4 || v - tag == 4) { isOk = true; break; } } if (!isOk) { verify = false; break; } } cout << (verify ? "pong" : "pang") << endl; } F:; return 0; } 第二题:循环二叉树 题目: 给你一颗二叉树,如图 ,编号的规则如图所示,现在站在第一个结点上,然后给你一串字符串,里面有‘L’、‘R’、‘B’,分别表示向左子树走,向右子树走,回退一步,问你最终你站在的那个结点的编号。 解析: 首先,特定编号的结点,它的左右子树的编号是确定的,因此我们先预处理下这个地方,搞一个数组映射一下;其次要回退,而且回退不止一步,所以,我们用一个栈保存我们走过的结点的编号,这样,如果回退就退栈。 代码: #include <bits/stdc++.h> using namespace std; // 0 : L 1 : R const int path[6][2] = { {0, 0}, {2, 3}, {3, 4}, {4, 5}, {5, 1}, {1, 2} }; int main() { string strs; while (cin >> strs) { int now = 1; stack<int> paths; paths.push(1); for (decltype(strs.size()) i = 0; i < strs.size(); i++) { if (strs[i] == 'B') { if (!paths.empty()) now = paths.top(), paths.pop(); } else paths.push(now), now = strs[i] == 'L' ? path[now][0] : path[now][1]; } cout << now << endl; } return 0; } 第三题:Utf8编码器 题目: 给你一个unicode对应utf8的转码规则的图,如图 ,然后给你UTF-8的编码,让你求出Unicode的编码,具体要求看题目 解析: 没什么技巧,直接if-else语句开搞就是了,代码比较多和长,因此要注意细节,看代码吧。 代码: ```C++ include <bits/stdc++.h> using namespace std; string getBinary(int x){ string ret; for (int i = 0; i < 8; i++, x /= 2) ret.push_back((char)(x % 2 + '0')); reverse(ret.begin(), ret.end()); return ret;} unsigned int getNum(string s){ unsigned int ret = 0; for (decltype(s.size()) i = 0; i < s.size(); i++) ret = ret * 2 + s[i] - '0'; return ret;} int main(){ while (true) { vector<int> arr; int n; char c; while (true) { if (EOF == scanf("%d%c", &n, &c)) goto F; arr.push_back(n); if (c == '\n') break; } vector<unsigned int> ans; bool isOk = true; for (decltype(arr.size()) i = 0; i < arr.size(); i++) { string s1 = getBinary(arr[i]); if (0 == s1.compare(0, 1, "0")) ans.push_back(getNum(s1.substr(1))); else { if (i + 1 < arr.size()) { string s2 = getBinary(arr[i + 1]); if (0 == s1.compare(0, 3, "110") && 0 == s2.compare(0, 2, "10")) { ans.push_back(getNum(s1.substr(3) + s2.substr(2))); i += 1; } else { if (i + 2 < arr.size()) { string s3 = getBinary(arr[i + 2]); if (0 == s1.compare(0, 4, "1110") && 0 == s2.compare(0, 2, "10") && 0 == s3.compare(0, 2, "10")) { ans.push_back(getNum(s1.substr(4) + s2.substr(2) + s3.substr(2))); i += 2; } else { if (i + 3 < arr.size()) { string s4 = getBinary(arr[i + 3]); if (0 == s1.compare(0, 5, "11110") && 0 == s2.compare(0, 2, "10") && 0 == s3.compare(0, 2, "10") && 0 == s4.compare(0, 2, "10")) { ans.push_back(getNum(s1.substr(5) + s2.substr(2) + s3.substr(2) + s4.substr(2))); i += 3; } else { if (i + 4 < arr.size()) { string s5 = getBinary(arr[i + 4]); if (0 == s1.compare(0, 6, "111110") && 0 == s2.compare(0, 2, "10") && 0 == s3.compare(0, 2, "10") && 0 == s4.compare(0, 2, "10") && 0 == s5.compare(0, 2, "10")) { ans.push_back(getNum(s1.substr(6) + s2.substr(2) + s3.substr(2) + s4.substr(2) + s5.substr(2))); i += 4; } else { if (i + 5 < arr.size()) { string s6 = getBinary(arr[i + 5]); if (0 == s1.compare(0, 7, "1111110") && 0 == s2.compare(0, 2, "10") && 0 == s3.compare(0, 2, "10") && 0 == s4.compare(0, 2, "10") && 0 == s5.compare(0, 2, "10") && 0 == s6.compare(0, 2, "10")) { ans.push_back(getNum(s1.substr(7) + s2.substr(2) + s3.substr(2) + s4.substr(2) + s5.substr(2) + s6.substr(2))); i += 5; } else { isOk = false; break; } } else { isOk = false; break; } } } else { isOk = false; break; } } } else { isOk = false; break; } } } else { isOk = false; break; } } } else { isOk = false; break; } } } if (!isOk) puts("no"); else { for (decltype(ans.size()) i = 0; i < ans.size(); i++) printf("%u%c", ans[i], i == ans.size() - 1 ? '\n' : ' '); } } F:; return 0; } ```
点赞 回复 分享
发布于 2017-10-09 22:10
蘑菇街2016研发工程师在线编程题 - 题解 FlushHip - http://blog.csdn.net/flushhip 今天无聊地蛋疼,所以在牛客网随便找了套题做做,随手写了下解题报告,套题链接:点这里 总体来说这套题就考了下贪心和模拟,最后一题考了一个经典的动态规划,其实也有别的方法可以搞,这题对于大家练手还是不错的. 第一题: 题目: 现在有一张半径为r的圆桌,其中心位于$(x,y)$,现在他想把圆桌的中心移到$(x_1,y_1)$。每次移动一步,都必须在圆桌边缘固定一个点然后将圆桌绕这个点旋转。问最少需要移动几步。 解析: 沿两圆心的直线移动是最短的,因此,固定的点固定在直线上,每次移动$2r$距离,快到目标点时,我们就不要把点固定在直线上了,以当前点和目标点的连线作为等腰三角形的底,两条半径做腰,这样三角形的顶点就是固定点,移动就是了。 代码: #include <bits/stdc++.h> using namespace std; double dis(int x, int y, int x1, int y1) { return sqrt(1.0 * (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y)); } int main() { int r, x, y, x1, y1; while (cin >> r >> x >> y >> x1 >> y1) { double ans = dis(x, y, x1, y1) / (2 * r); cout << ceil(ans) << endl; } return 0; } 第二题: 题目: 给定一个递增序列,$a1 <a_2 <...<a_n$ 。定义这个序列的最大间隔为$d=max{a{i+1} - ai }(1≤i<n)$,现在要从$a2 ,a_3 ...,a{n-1}$ 中删除一个元素。问剩余序列的最大间隔最小是多少? 解析: 先预处理下原序列每两个元素的间隔,然后就开始删元素,这里有个技巧,我们在第一遍预处理的时候就求出一个间隔的最大值,然后删元素的时候,如果没删掉这个最大值,那么就把新得到的一个间隔(前后两个间隔相加)和这个最大值比较,如果删掉了这个最大值,那么新得到的间隔一定比这个最大值大,即$ans = min(ans, max(maxInter, inter[i] + inter[i + 1]))$. 代码: #include <bits/stdc++.h> using namespace std; int main() { int n; while (cin >> n) { int *a = new int[n], *inter = new int[n]; cin >> a[0]; int maxInter = 0; for (int i = 1; i < n; i++) cin >> a[i], inter[i] = a[i] - a[i - 1], maxInter = max(maxInter, inter[i]); if (n == 1) { cout << 0 << endl; break; } if (n == 2) { cout << maxInter << endl; break; } int ans = 0x3f3f3f3f; for (int i = 1; i < n - 1; i++) ans = min(ans, max(maxInter, inter[i] + inter[i + 1])); cout << ans << endl; } return 0; } 第三题: 题目: A和B是好友,他们经常在空闲时间聊天,A的空闲时间为$[a_1 ,b_1 ],[a_2 ,b_2 ]...[a_p ,b_p ]$。B的空闲时间是$[c_1 +t,d_1 +t]...[c_q +t,d_q +t]$,这里t为B的起床时间。这些时间包括了边界点。B的起床时间为$[l,r]$的一个时刻。若一个起床时间能使两人在某一时刻聊天,那么这个时间就是合适的,问有多少个合适的起床时间? 解析: 题目表达不清,这是我改了下的题意,直接暴力就好了,求区间交,应该都会吧. 代码: #include <bits/stdc++.h> using namespace std; typedef struct tagInterval Interval; typedef Interval *pInterval; struct tagInterval { int left, right; }; int main() { int p, q, l, r; while (cin >> p >> q >> l >> r) { pInterval A = new Interval[p], B = new Interval[q]; for (int i = 0; i < p; i++) cin >> A[i].left >> A[i].right; for (int i = 0; i < q; i++) cin >> B[i].left >> B[i].right; int ans = 0; for (int i = l; i <= r; i++) { for (int x = 0; x < p; x++) { for (int y = 0; y < q; y++) { if ((A[x].left <= B[y].left + i && B[y].left + i <= A[x].right) || (A[x].left <= B[y].right + i && B[y].right + i <= A[x].right)) { ++ans; goto F; } } } F:; } cout << ans << endl; delete[] A; delete[] B; } return 0; } 第四题: 题目: 有一个投篮游戏。球场有p个篮筐,编号为$0,1...,p-1$。每个篮筐下有个袋子,每个袋子最多装一个篮球。有n个篮球,每个球编号$x_i$ 。规则是将数字为$x_i$ 的篮球投到$x_i$除p的余数为编号的袋里。若袋里已有篮球则球弹出游戏结束输出i,否则重复至所有球都投完。输出-1。问游戏最终的输出是什么? 解析: 这题就是考一下在线处理...... 代码: #include <bits/stdc++.h> using namespace std; int main() { int p, n; while (cin >> p >> n) { bool *ba = new bool[p]; memset(ba, false, sizeof(bool) * p); bool isOver = false; for (int i = 1; i <= n; i++) { int x; cin >> x; if (isOver) continue; if (ba[x % p]) { cout << i << endl; isOver = true; } else ba[x % p] = true; } if (!isOver) cout << -1 << endl; delete[] ba; } return 0; } 第五题: 题目: 给定一个字符串,问是否能通过添加一个字母将其变为回文串。 解析: 求原串和反串的最长公共子序列,如果最长公共子序列的长度是字符串的长度或者是字符串的长度减一,那么就是可行的;看到有人是这么做的:既然可以添加一个字符变成回文串,那么就可以删除一个字符变成回文串,因此,枚举删除每个字符,再判每个字符串是不是回文串,这也是可以的,不过时间复杂度有点高. 代码: #include <bits/stdc++.h> using namespace std; int main() { string str; while (cin >> str) { string rev = str; reverse(rev.begin(), rev.end()); int dp[(const int)(str.size() + 5)][(const int)(str.size() + 5)]; memset(dp, 0, sizeof(dp)); // dp[0][0] = 1; for (int i = 0; i < str.size(); i++) { for (int j = 0; j < str.size(); j++) { if (str[i] == rev[j]) dp[i + 1][j + 1] = dp[i][j] + 1; else dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j]); } } // cout << dp[str.size()][str.size()] << endl; puts(dp[str.size()][str.size()] == str.size() || dp[str.size()][str.size()] == str.size() - 1 ? "YES" : "NO"); } return 0; }
点赞 回复 分享
发布于 2017-10-04 14:37

相关推荐

不愿透露姓名的神秘牛友
07-08 12:10
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
昨天 11:30
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
06-11 13:34
offe从四面八方来:我真的没时间陪你闹了
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
13
分享

创作者周榜

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