微软笔试题

March 27th, 2016

1st question

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 question

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 question

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[N].begin(), rights[N].end());
	if (min_right != NO)
		cout << min_right << '\n';
	else
		cout << "No\n";
}

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




你可能感兴趣的:(C++,dynamic,programming,微软)