Codeforces Round #256 (Div. 2)

来源:互联网 发布:苏州110网络报警平台 编辑:程序博客网 时间:2024/06/11 12:04

A, B题不多说

C题:

题意:给你n个相邻的木板, 每个木板宽度为1, 高度为ai,给你一把刷子, 每一次能刷宽度为1的连续的木板, 问最少刷几次能使全部木板换一种颜色

 分析:答案最大为n, 就是每次都竖着刷, 若存在先横着刷的情况 则一定是把n个木板中最小的高度全部刷掉, 这样相当于每个木板的高度减去最小高度后需要的次数, 加上最小木板的高度, 递归求解

 

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int n, a[5010];int dfs(int l, int r) {   int res = 0;   int min_v = 1 << 30;   for(int i=l; i<=r; i++) min_v = min(min_v, a[i]);   for(int i=l; i<=r; i++) a[i] -= min_v;   res += min_v;   for(int i=l; i<=r; i++) if(a[i]) {     for(int j=i; j<=r; j++) {        if(a[j] == 0) {           res += dfs(i, j-1);           i = j;           break;        }        else if(a[j] && j == r) {            res += dfs(i, j);            i = j;            break;        }     }   }   return min(res, r-l+1);}int main() {  scanf("%d", &n);  for(int i=1; i<=n; i++) scanf("%d", &a[i]);  printf("%d\n", dfs(1, n));  return 0;}

D题:

题意:给你一个n*m的矩阵, i, j位子的大小为i*j, 求第k小的数

分析:二分求解,一开始最小值为1, 最大值为n*m,二分球的mid = (n + m) >> 1, 求小于等于Mid的数 

for(int i=1; i<=n; i++) res += min(m, mid / n), 不过感觉还是有问题, 难道不会最后二分球的一个不存在的值满足条件吗, 虽然一直没有找到反例

#include <cstdio>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;int n, m;ll k;ll f(ll x) {  ll res = 0;  for(int i=1; i<=n; i++)    res += min((ll)m, x / i);  return res;}int main() {  cin >> n >> m >> k;  ll l = 1, r = (ll)n * m;  ll ans = -1;  while(l <= r) {    ll mid = (l + r) >> 1;    if(f(mid) >= k) {        ans = mid;        r = mid - 1;    }    else        l = mid + 1;  }  printf("%I64d\n", ans);  return 0;}


E题:

题意:给你x, k, f()是每一数的因子的递增排列, xi = f(x i -1), 求x(k);

分析:dfs递归求解, 搜索的过程就像一颗搜索树

#include <cstdio>#include <cstring>#include <vector>#include <algorithm>#include <iostream>using namespace std;typedef long long ll;ll a[1000010], x, k;ll sum, tot;vector <ll> div1[111111];void dfs(ll cnt, ll cur) {  if(sum >= 100000)  return;  if(cnt == 1) {    printf("1 ");    sum++;    return;  }  if(cur == 0) {    printf("%I64d ", a[cnt]);    sum++;    return;  }  for(ll i=0; i<div1[cnt].size(); i++) {     dfs(div1[cnt][i], cur - 1);     if(sum >= 100000)  return;  }}int main() {  cin >> x >> k;  sum = 0;  tot = 0;  for(ll i=1; i*i <= x; i++) if(x % i == 0) {    a[++tot] = i;    if(i*i != x) a[++tot] = x / i;  }  sort(a+1, a+tot+1);  for(ll i=1; i<=tot; i++)    for(ll j=1; j<=i; j++) if(a[i] % a[j] == 0)      div1[i].push_back(j);  dfs(tot, k);  return 0;}


0 0