您的位置:首页 > 编程语言 > C语言/C++

微软笔试题

2016-03-29 18:37 288 查看
March 27th, 2016

1st problem

hihocoder 1283. hiho密码

#include <iostream>
#include <vector>

using namespace std;

int main() {
int N;
cin >> N;
int increment_cnt = 0;
vector<int> nums(N);
cin >> nums[0];
for (int i = 1; i < N; ++ i) {
cin >> nums[i];
increment_cnt = nums[i] > nums[i-1]? increment_cnt + 1: 1;
}
for (int i = 0; i < N - increment_cnt; ++ i) {
cout << nums[i];
if (i != N - increment_cnt - 1)
cout << " ";
}
if (increment_cnt == N)
cout << 1 << '\n';
}

2. 2rd problem

hihocoder 1284. 机会渺茫

Do remember define N and M as uint64_t instead of int !!!

#include <unordered_set>
#include <iostream>
#include <cstdint>
#include <cmath>

using namespace std;

uint64_t gcd(uint64_t a, uint64_t b) {
if (b == 0)
return a;
else
return gcd(b, a % b);
}

int main() {
uint64_t N, M;
cin >> N >> M;
unordered_set<uint64_t> ns, ms;
uint64_t n = sqrt(N), m = sqrt(M);
for (uint64_t i = 1; i <= n; ++ i)
if (N % i == 0) {
ns.insert(i);
if (ns.find(N / i) == ns.end())
ns.insert(N / i);
}
uint64_t match = 0;
for (uint64_t i = 1; i <= m; ++ i)
if (M % i == 0) {
ms.insert(i);
match += (ns.find(i)!=ns.end()? 1: 0);
if (ms.find(M / i) == ms.end()) {
ms.insert(M / i);
match += (ns.find(M/i)!=ns.end()? 1: 0);
}
}
uint64_t divisor = gcd(ns.size() * ms.size(), match);
cout << ns.size()*ms.size()/divisor << " " << match/divisor << '\n';
}


3rd problem

Hihocoder 1285. 智力竞赛 -- Two dimensional dynamic programming. 

rights[i][j]

    i: # of stages we have passed

    j: j chances we have used 

    rights[i][j]: the minimal right answers we have to make in j chances, to pass thei# stage

Given ai, s, t, max_chances, we could find out all the solutions(x right answers && y wrong ones) to get the points, which is no less than ai. 

    1. In every rights[i][j], max_chances = M - j.

    2. When j + x + y <= M, we have dynamic equation:

rights[i+1][j+x+y] = min(rights[i+1][j+x+y], rights[i][j] + y);

Source:

#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cassert>

using namespace std;

// first: ans_num, second: right ones among answers
// sorted by first -- less<int>
vector<pair<int, int>> get_solutions(int require, int max_chances, int S, int T) {
vector<pair<int, int>> res;
for (int wrong = 0;
wrong <= max_chances && (wrong-1) * T < require; ++ wrong) {
int right = ceil((require - wrong * T) * 1.0 / S);
if (wrong + right > max_chances)
break;
res.emplace_back(make_pair(wrong+right, right));
}
return res;
}

void gao() {
// input
int N, M, S, T;
cin >> N >> M >> S >> T;
const int NO = M + 1;
vector<int> A;
for (int i = 0; i < N; ++ i) {
int a;
cin >> a;
A.push_back(a);
}

// right[i][j]
// i: i# stage ("guan" in Chinese)
// j: # of chance has been used
// value: # of right answer in j answers
vector<vector<int>> rights(N+1, vector<int>(M+1, NO));
// dp init
rights[0][0] = 0;
for (int i = 0; i <= N-1; ++ i) {
int chance_used = NO;
for (int j = 0; j <= M; ++ j)
if (rights[i][j] != NO) {
chance_used = j;
break;
}
if (chance_used == NO) {
cout << "No\n";
return;
}
auto solutions = get_solutions(A[i], M - chance_used, S, T);
for (int j = chance_used; j <= M && rights[i][j] != NO; ++ j)
for (auto solution: solutions)
if (j + solution.first <= M)
rights[i+1][j+solution.first] =
min(rights[i+1][j+solution.first], rights[i][j] + solution.second);
else
break;
}

int min_right = *min_element(rights
.begin(), rights
.end());
if (min_right != NO)
cout << min_right << '\n';
else
cout << "No\n";
}

int main() {
int Q;
cin >> Q;
while (Q-- != 0) {
gao();
}
}

April 6th, 2016

1st problem -- Hihocoder 1288. Font Size

Misunderstand the ceil and floor, their meanings are:

    - ceil, 天花板,上界

    - floor, 下界

Source:

#include <iostream>
#include <vector>
#include <numeric>
#include <cmath>

using namespace std;

void gao() {
int n, p, w, h;
cin >> n >> p >> w >> h;
vector<int> characters(n);
for (size_t i = 0; i < characters.size(); ++ i)
cin >> characters[i];
for (int s = min(w, h); s >= 1; -- s) {
int lines = p * (h / s);
auto acc = [s, w](int sum, int c) { return sum + ceil(1.0 * c / (w / s)); };
if (accumulate(characters.begin(), characters.end(), 0, acc) <= lines) {
cout << s << '\n';
return ;
}
}
}

int main() {
int tasks;
cin >> tasks;
while (tasks --)
gao();
}


2rd problem -- Hihocoder 1289. 403 Forbidden

It's a simulation problem.

'Cause 1 <= N, M <= 100000, we will get TLE if we solve the problem with time complexity O(NM). 

Here I proposal a Huffman tree to solve this problem in O(N + M).

Huffman Tree Construction

The rule will be inserted into the tree only if its "Huffman Tree path" contains no rule.

Say we have rules A, B, C, D to construct the tree, where A= "deny 0010/3", B = "allow 0011/3", C = "allow 0011/4", D = "allow 0001/2":

    1. A is inserted into the tree, 'cause there is no rule before.

    2. B will not be inserted into the tree, 'cause A with the same prefix(001) has showed up before, which could be reasoned in your logic.

    3. C will not be inserted into the tree neither because of the same reason as B.

    4. D will be inserted into the tree because of the same reason as A.

Thus we can ensure the tree have following properties:

    1. the deeper the node is, the more earlier it has appeared.

    2. And we have cut off the useless rules which are more restrict than rules appearing before.

IP match

    1. Thus we would go down with the prefix of IP, and reach nodeN

    2. find out whether N stands for a rule, or it could be the internal node of the other rule.

        2.1. If yes, we are done.

        2.2 If not, find N's parent, repeat the first step.

Example:

    1. Image when we request with ip = "0011". Even ip matches B, C, it
matches A
first. B, C won't work.

    2. Image when we request with ip = "0000". Then it matches D.

Source:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <memory>

using namespace std;

class RuleNode {
public:
void insert(const string& type, unsigned int ip, int mask_cnt) {
// the more loose or equivalently strict rule has appeared before.
if (rule_) { return ; }

if (mask_cnt == 0) {
allow_ = type == "allow";
rule_ = true;
return;
}

if (most_siginificant_bit(ip) == LEFT_) {
if (left_ == nullptr) left_ = make_shared<RuleNode>();
left_->insert(type, ip << 1, -- mask_cnt);
} else {
if (right_ == nullptr) right_ = make_shared<RuleNode>();
right_->insert(type, ip << 1, -- mask_cnt);
}
}

bool match(unsigned int ip) {
if (most_siginificant_bit(ip) == LEFT_) {
if (left_ != nullptr) {
if (left_->match(ip << 1)) return true;
}
} else {
if (right_ != nullptr) {
if (right_->match(ip << 1)) return true;
}
}
if (rule_) {
cout << (allow_? "YES": "NO") << endl;
return true;
} else {
return false;
}
}

inline unsigned int most_siginificant_bit(unsigned int ip) {
return (ip & (1 << 31));
}

private:
bool allow_ = false;
bool rule_ = false;
shared_ptr<RuleNode> left_ = nullptr;
shared_ptr<RuleNode> right_ = nullptr;
const static int LEFT_ = 0;
};

unsigned int parse_ip(string& str) {
unsigned int ip = 0;
for (int i = 0; i < 3; ++ i) {
size_t len = str.find('.');
ip = ip * 256 + stoi(str.substr(0, len));
str = str.substr(len + 1);
}
size_t len = str.find('/');
ip = ip * 256 + stoi(str.substr(0, len));
str = len != string::npos? str.substr(len + 1): "";
return ip;
}

int main() {
int n, m;
cin >> n >> m;
shared_ptr<RuleNode> root(new RuleNode());

while (n-- != 0) {
// type
string type;
cin >> type;
// ip and mask
string ip_and_mask;
cin >> ip_and_mask;
unsigned int ip = parse_ip(ip_and_mask);
// mask_cnt
unsigned int mask_cnt;
if (ip_and_mask != "") {
mask_cnt = stoi(ip_and_mask);
} else {
mask_cnt = 32;
}
// insert
root->insert(type, ip, mask_cnt);
}

while (m -- != 0) {
string str;
cin >> str;
if (! root->match(parse_ip(str))) { cout << "YES" << endl; }
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  微软 C++