喵哈哈村的魔法考试 Round 16 (Div.2) 比赛题解

A

实际上我们for一遍就好。

坑点就是会爆int

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
long long ans1,ans2,a[maxn],b[maxn],c[maxn];
int n;
int main(){
    while(cin>>n){
        ans1 = -1;
        for(int i=1;i<=n;i++){
            cin>>a[i]>>b[i]>>c[i];
            if(a[i]*b[i]*c[i]>ans1){
                ans1 = a[i]*b[i]*c[i];
                ans2 = i;
            }
        }
        cout<<ans2<<endl;
    }
}

B . 两数组找相同的元素

我们对于B的每一个元素,在A中进行二分判断是否存在即可。

也可以使用C++内带的.find函数

#include <cstdio>
#include <unordered_set>
#include <vector>

using namespace std;

int main(int argc, const char *argv[])
{
    unordered_set<int> first_array;
    int m, n;
    scanf("%d %d", &m, &n);
    int tmp;
    for (int i = 0; i < m; i++) {
        scanf("%d", &tmp);
        first_array.emplace(tmp);
    }

    vector<int> ans;
    for (int i = 0; i < n; i++) {
        scanf("%d", &tmp);
        if (first_array.find(tmp) != first_array.end()) {
            ans.push_back(tmp);
        }
    }
    for (int i = 0; i < ans.size(); ++i) {
        printf("%d%c", ans[i], i + 1 == ans.size() ? '\n' : ' ');
    }

    return 0;
}

B . DAU统计

实际上我们对于每一个元素,如果这个元素之前并没有出现过,那么对答案的贡献就加一。

于是我们可以用hash每次O(1)的判断这个元素之前是否出现过即可。

也可以使用set去维护也可以。

// Copyright 2017 He Tianyi <hetianyi@bytedance.com>

// Compiler opts: g++ -g -std=c++11 -o dau -O2 -Wall -Werror dau.cc

#include <cstdint>

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

static const size_t kMergeThreshold = 170000;

class UserMap {
 public:
  UserMap() {
    base_ = std::unique_ptr<std::vector<uint64_t>>(
        new std::vector<uint64_t>());
  }

  void Merge() {
    std::vector<uint64_t> *result = new std::vector<uint64_t>();
    result->reserve(base_->size() + delta_.size());
    auto base_it = base_->begin();
    auto delta_it = delta_.begin();
    while (base_it != base_->end() || delta_it != delta_.end()) {
      if (delta_it == delta_.end()) {
        result->emplace_back(*base_it);
        base_it++;
      } else if (base_it == base_->end()) {
        result->emplace_back(*delta_it);
        delta_it++;
      } else {
        if (*base_it < *delta_it) {
          result->emplace_back(*base_it);
          base_it++;
        } else {
          result->emplace_back(*delta_it);
          delta_it++;
        }
      }
    }
    base_.reset(result);
    delta_.clear();
  }

  bool PutIfAbsent(uint64_t uid) {
    if (delta_.find(uid) != delta_.end()) {
      return false;
    }
    if (std::binary_search(base_->begin(), base_->end(), uid)) {
      return false;
    }
    delta_.insert(uid);
    if (delta_.size() > kMergeThreshold) {
      Merge();
    }
    return true;
  }

 private:
  std::unique_ptr<std::vector<uint64_t>> base_;
  std::set<uint64_t> delta_;
};

int main(int argc, char** argv) {
  uint64_t uid;
  UserMap m;
  uint32_t result = 0;
  do {
    std::cin >> uid;
    if (uid > 0 && m.PutIfAbsent(uid)) {
      result++;
    }
  } while (uid != 0);
  std::cout << result << std::endl;
  return 0;
}

D . 形式化计算

题面分为两个部分,计算部分和输出部分。

计算部分比较简单,我们对于每个符号进行判断即可。

计算部分结束之后,我们要处理输出。

输出我们需要对每个数字/符号单独输出。可以观察到,每个字符实际上都是一个矩阵,所以我们可以预处理出每个字符矩阵的样子,然后输出即可。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a,b;
char s[10];
char drawBoard[5][200];
void print1(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[1][startCol] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[3][startCol] = '*';
	drawBoard[4][startCol] = '*';
	startCol = startCol + 3;
}
void print2(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[0][startCol+1] = '*';
	drawBoard[0][startCol+2] = '*';
	drawBoard[1][startCol+2] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[3][startCol] = '*';	
	drawBoard[4][startCol] = '*';
	drawBoard[4][startCol+1] = '*';
	drawBoard[4][startCol+2] = '*';
	startCol = startCol + 5;
}
void print3(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[0][startCol+1] = '*';
	drawBoard[0][startCol+2] = '*';
	drawBoard[1][startCol+2] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[3][startCol+2] = '*';
	drawBoard[4][startCol] = '*';
	drawBoard[4][startCol+1] = '*';
	drawBoard[4][startCol+2] = '*';
	startCol = startCol + 5;
}
void print4(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[0][startCol+2] = '*';
	drawBoard[1][startCol] = '*';
	drawBoard[1][startCol+2] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[3][startCol+2] = '*';
	drawBoard[4][startCol+2] = '*';
	startCol = startCol + 5;
}
void print5(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[0][startCol+1] = '*';
	drawBoard[0][startCol+2] = '*';
	drawBoard[1][startCol] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[3][startCol+2] = '*';
	drawBoard[4][startCol+2] = '*';
	drawBoard[4][startCol+1] = '*';
	drawBoard[4][startCol] = '*';
	startCol = startCol + 5;
}
void print6(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[0][startCol+1] = '*';
	drawBoard[0][startCol+2] = '*';
	drawBoard[1][startCol] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[3][startCol] = '*';
	drawBoard[3][startCol+2] = '*';
	drawBoard[4][startCol] = '*';
	drawBoard[4][startCol+1] = '*';
	drawBoard[4][startCol+2] = '*';
	startCol = startCol + 5;
}
void print7(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[0][startCol+1] = '*';
	drawBoard[0][startCol+2] = '*';
	drawBoard[1][startCol+2] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[3][startCol+2] = '*';
	drawBoard[4][startCol+2] = '*';
	startCol = startCol + 5;
}
void print8(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[0][startCol+1] = '*';
	drawBoard[0][startCol+2] = '*';
	drawBoard[1][startCol] = '*';
	drawBoard[1][startCol+2] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[3][startCol] = '*';
	drawBoard[3][startCol+2] = '*';
	drawBoard[4][startCol] = '*';
	drawBoard[4][startCol+1] = '*';
	drawBoard[4][startCol+2] = '*';
	startCol = startCol + 5;
}
void print9(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[0][startCol+1] = '*';
	drawBoard[0][startCol+2] = '*';
	drawBoard[1][startCol] = '*';
	drawBoard[1][startCol+2] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[3][startCol+2] = '*';
	drawBoard[4][startCol] = '*';
	drawBoard[4][startCol+1] = '*';
	drawBoard[4][startCol+2] = '*';
	startCol = startCol + 5;
}
void print0(int &startCol) {
	drawBoard[0][startCol] = '*';
	drawBoard[0][startCol+1] = '*';
	drawBoard[0][startCol+2] = '*';
	drawBoard[1][startCol] = '*';
	drawBoard[1][startCol+2] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[3][startCol] = '*';
	drawBoard[3][startCol+2] = '*';
	drawBoard[4][startCol] = '*';
	drawBoard[4][startCol+1] = '*';
	drawBoard[4][startCol+2] = '*';
	startCol = startCol + 5;
}
void printjia(int &startCol) {
	drawBoard[1][startCol+1] = '*';
	drawBoard[2][startCol] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[2][startCol+2] = '*';
	drawBoard[3][startCol+1] = '*';
	startCol = startCol + 5;
}
void printjian(int &startCol) {
	drawBoard[2][startCol] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[2][startCol+2] = '*';
	startCol = startCol + 5;
}
void printcheng(int &startCol) {
	drawBoard[1][startCol] = '*';
	drawBoard[1][startCol+2] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[3][startCol] = '*';
	drawBoard[3][startCol+2] = '*';
	startCol = startCol + 5;
}
void printchu(int &startCol) {
	drawBoard[1][startCol+2] = '*';
	drawBoard[2][startCol+1] = '*';
	drawBoard[3][startCol] = '*';
	startCol = startCol + 5;
}
void printequal(int &startCol) {
	drawBoard[1][startCol] = '*';
	drawBoard[1][startCol+1] = '*';
	drawBoard[1][startCol+2] = '*';
	drawBoard[1][startCol+3] = '*';
	drawBoard[3][startCol] = '*';
	drawBoard[3][startCol+1] = '*';
	drawBoard[3][startCol+2] = '*';
	drawBoard[3][startCol+3] = '*';
	startCol = startCol + 6;
}
void printdian(int &startCol) {
	drawBoard[3][startCol] = '*';
	drawBoard[3][startCol+1] = '*';
	drawBoard[4][startCol] = '*';
	drawBoard[4][startCol+1] = '*';
	startCol = startCol + 4;
}
void drawNum(double x,int &startCol) {
	char s[100];
	memset(s,0,sizeof(s));
	if (x-int(x) == 0) sprintf(s,"%d",int(x));
	else if (x*10-int(x*10)==0) sprintf(s,"%.1lf",x);
	else sprintf(s,"%.2lf",x);
	
	for (int i=0;i<strlen(s);++i) {
		switch (s[i]) {
			case '0':print0(startCol);break;
			case '1':print1(startCol);break;
			case '2':print2(startCol);break;
			case '3':print3(startCol);break;
			case '4':print4(startCol);break;
			case '5':print5(startCol);break;
			case '6':print6(startCol);break;
			case '7':print7(startCol);break;
			case '8':print8(startCol);break;
			case '9':print9(startCol);break;
			case '.':printdian(startCol);break;
			case '-':printjian(startCol);break;
		}
	}
}
int main() {

	scanf("%d %s %d",&a,s,&b);
	
	for (int i=0;i<5;++i)
		for (int j=0;j<200;++j)
			drawBoard[i][j] = ' ';	
	double c=0;	
	int startCol=0;
	drawNum(a,startCol);

	switch (s[0]) {
		case '+':c = a+b; printjia(startCol);break;
		case '-':c = a-b; printjian(startCol);break;
		case '*':c = a*b; printcheng(startCol);break;
		case '/':c = 1.0*a/b; printchu(startCol);break;
	}
	drawNum(b,startCol);
	printequal(startCol);
	drawNum(c,startCol);
	for (int i=0;i<5;++i,cout<<endl)
		for (int j=0;j<startCol;++j)
			cout<<drawBoard[i][j];

	return 0;
}

E . 任务执行策略

动态规划题。

首先把三角形翻转一下,倒着来考虑每个元素。

dp[i][j][k]表示考虑到第(i,j)个,当前选取了k个元素的最大值。

前缀和维护最大值,就可以把转移优化到O(1)。

#include <algorithm>
#include <cassert>
#include <cstring>
#include <cstdio>

const int N = 60;
const int M = 500 + 10;

int dp[N][N][M], sum[N][N], a[N][N], n, m;

int main() {
    assert(scanf("%d%d", &n, &m) == 2);
    assert(1 <= n && n <= 50);
    assert(1 <= m && m <= 500);
    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= i; ++ j) {
            assert(scanf("%d", &a[i][j]) == 1);
            assert(0 <= a[i][j] && a[i][j] <= 1000);
        }
    }

    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= i; ++ j) {
            sum[i][j] = sum[i][j - 1] + a[n - j + 1][i - j + 1];
        }
    }

    memset(dp, 200, sizeof(dp));
    for (int i = 0; i <= n; ++ i) {
        dp[i][0][0] = 0;
    }
    for (int i = 1; i <= n; ++ i) {
        for (int j = i; j >= 0; -- j) {
            for (int k = j; k <= m; ++ k) {
                dp[i][j][k] = std::max(dp[i][j + 1][k],
                                       dp[i - 1][std::max(0, j - 1)][k - j] + sum[i][j]);
            }
        }
    }
    printf("%d\n", dp[n][0][m]);
    return 0;
}
posted @ 2017-04-22 22:49  qscqesze  阅读(286)  评论(0编辑  收藏  举报