1. 程式人生 > >吉位元2018春招技術類筆試試卷程式設計題

吉位元2018春招技術類筆試試卷程式設計題

吉位元的程式設計題倒是不難,但是它的選擇題和填空題是真的多。。。

由於沒有拍題目,所以我就按照我的記憶來描述一下題目了。

第一題

題目

判斷兩個數,換成二進位制格式,輸出多少個位置不一樣

解析

這題很基礎,取出每一位上的二進位制,用異或比較就行了。看程式碼。

程式碼

#include <bits/stdc++.h>

using namespace std;

int main()
{
    for (int n1, n2; cin >> n1 >> n2; ) {
        int ans = 0;
        unsigned
int n_1 = n1, n_2 = n2; for (int i = 0; i < 32; i++) { ans += (n_1 & 1) ^ (n_2 & 1); n_1 >>= 1; n_2 >>= 1; } cout << ans << endl; } return 0; }

第二題

題目

n個三維空間點,判斷最多多少個空間點在同一條直線上

解析

這題儘量不要用斜率做,用向量做是最好的,那麼問題就轉化成了如何判斷兩個向量共線;

只要兩個向量對應係數成比例,那麼這兩個向量就共線;

由於n達到了2000,那麼三層for迴圈列舉三個點的演算法是行不通的,因此,換一種思路,假設兩個向量共線,且這兩個向量的起點是同一個點,那麼這說明三點就共線了;

因此,我們把空間點排序,排序函式:

bool operator<(const Point &other) const {
        if (x != other.x)
            return x < other.x;
        if (y != other.y)
            return y < other.y;
        if
(z != other.z) return z < other.z; }

這樣可以保證待會我們以一個點作為起點去構造其他向量的時候能保證向量都在第一卦限;

由於共線向量對應係數成比例,因此,我們直接把共線的向量統一化成最簡的形式,即三個分量沒有除了1沒有其他公約數,這樣就可以用一個map來儲存最簡式,最後求出共線最多的最簡式的數量加一就是答案。

時間複雜度:O(n2logn)

程式碼

#include <bits/stdc++.h>

using namespace std;

#define gcd __gcd

struct Point {
    int x, y, z;
    Point() {}
    Point(int x, int y, int z) : x(x), y(y), z(z) {}

    bool operator<(const Point &other) const {
        if (x != other.x)
            return x < other.x;
        if (y != other.y)
            return y < other.y;
        if (z != other.z)
            return z < other.z;
    }
};

typedef pair<pair<int, int>, int> Node;

int main()
{
    for (int n; cin >> n; ) {
        vector<Point> points;
        for (int i = 0, x, y, z; i < n; i++)
            cin >> x >> y >> z, points.push_back(Point(x, y, z));
        sort(points.begin(), points.end());

        int ans = 0;
        for (int i = 0; i < n; i++) {
            map<Node, int> mp;
            for (int j = i + 1; j < n; j++) {
                int vx = points[j].x - points[i].x;
                int vy = points[j].y - points[i].y;
                int vz = points[j].z - points[i].z;
                int g = gcd(gcd(vx, vy), vz);
                mp[make_pair(make_pair(vx / g, vy / g), vz / g)]++;
            }
            int sum = 0;
            for (auto it = mp.begin(); it != mp.end(); ++it)
                sum = max(sum, it->second);
            ans = max(sum, ans);
        }
        cout << ans + 1 << endl;
    }
    return 0;
}