Codeforces Beta Round #6 (Div. 2 Only)

A,B,C都是水题。。。

D题,直接爆搜。我换了好多姿势,其实最简单的方法,就能过。

#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
using namespace std;
int que[50];
int p[50];
int o[50];
int temp[50];
int st[50];
int ans,minz;
int n,a,b;
void dfs(int x,int sum)
{
    int i;
    if(sum >= minz) return;
    if(x == n)
    {
        for(i = 1;i <= n;i ++)
        temp[i] = p[i];
        for(i = 2;i <= n-1;i ++)
        {
            temp[i] -= o[i]*a;
            temp[i-1] -= o[i]*b;
            temp[i+1] -= o[i]*b;
        }
        for(i = 2;i <= n-1;i ++)
        {
            if(temp[i] >= 0) break;
        }
        if(i == n)
        {
            if(sum < minz)
            {
                minz = sum;
                for(i = 2;i <= n-1;i ++)
                st[i] = o[i];
            }
        }
        return ;
    }
    for(i = 0;i <= 8;i ++)
    {
        o[x] = i;
        dfs(x+1,sum+i);
    }
}
int main()
{
    int i,j;
    scanf("%d%d%d",&n,&a,&b);
    for(i = 1; i <= n; i ++)
    {
        scanf("%d",&p[i]);
    }
    while(p[1] >= 0)
    {
        que[ans++] = 2;
        p[1] -= b;
        p[2] -= a;
        p[3] -= b;
    }
    while(p[n] >= 0)
    {
        que[ans++] = n-1;
        p[n-2] -= b;
        p[n] -= b;
        p[n-1] -= a;
    }
    for(i = 1;i <= n;i ++)
    {
        if(p[i] >= 0) break;
    }
    if(i == n+1)
    {
        printf("%d
",ans);
        for(i = 0;i < ans;i ++)
        printf("%d ",que[i]);
        printf("
");
        return 0;
    }
    minz = 1000;
    dfs(2,0);
    printf("%d
",minz+ans);
    for(i = 0;i < ans;i ++)
    printf("%d ",que[i]);
    for(i = 2;i <= n-1;i ++)
    {
        for(j = 1;j <= st[i];j ++)
        printf("%d ",i);
    }
    printf("
");
    return 0;
}
View Code

 E题,二分+rmq之类的,能求区间最值的算法。

题意是比较扯,按章节排列的n本书,要展示,最长能展示多少本,这一段的高度差要小于等于k,再输出总共多少中情况,把起点,终点输出。

rmq好久没写过了啊,记不得 什么东西了。

#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
using namespace std;
int n,k;
int p[100001];
int dpmin[22][100001];
int dpmax[22][100001];
int bin[30];
void CL(int n)
{
    int i,j;
    for(i = 1;i <= n;i ++)
    {
        dpmin[0][i] = p[i];
        dpmax[0][i] = p[i];
    }
    for(i = 1;bin[i] <= n;i ++)
    {
        for(j = 1;j + bin[i-1] <= n;j ++)
        {
            dpmin[i][j] = min(dpmin[i-1][j],dpmin[i-1][j+bin[i-1]]);
            dpmax[i][j] = max(dpmax[i-1][j],dpmax[i-1][j+bin[i-1]]);
        }
    }
}
int rmqmax(int s,int t)
{
    int k = log((t-s+1)*1.0)/log(2.0);
    return max(dpmax[k][s],dpmax[k][t-bin[k]+1]);
}
int rmqmin(int s,int t)
{
    int k = log((t-s+1)*1.0)/log(2.0);
    return min(dpmin[k][s],dpmin[k][t-bin[k]+1]);
}
int query(int s,int t)
{
    return rmqmax(s,t) - rmqmin(s,t);
}
int judge(int mid)
{
    int i,ans = 0;
    for(i = 1;i <= n-mid+1;i ++)
    {
        if(query(i,i+mid-1) <= k)
        ans ++;
    }
    return ans;
}
int main()
{
    int i,j,str,end,mid;
    scanf("%d%d",&n,&k);
    for(i = 1;i <= n;i ++)
    scanf("%d",&p[i]);
    bin[0] = 1;
    for(i = 1;i <= 22;i ++)
    bin[i] = bin[i-1]*2;
    CL(n);
    str = 1;
    end = n;
    while(str < end)
    {
        mid = (str + end + 1)/2;
        if(judge(mid))
        str = mid;
        else
        end = mid - 1;
    }
    printf("%d %d
",end,judge(end));
    for(i = 1;i <= n-end+1;i ++)
    {
        if(query(i,i+end-1) <= k)
        {
            printf("%d %d
",i,i+end-1);
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/naix-x/p/3673619.html