机房测试8.24

对着背影说爱祢 提交于 2020-02-15 06:04:16

keys

简单贪心(idy002原话)

我反正是不信的。

要点是证明选择的钥匙一定是连续的n个。

可通过三个点两个人一个办公室之间的选择优劣来进行理解。

问题是为什么输出距离最大值就可以AC?

idy002老师的数据已经日渐生命之源(水)了。

忆往昔线段树0分程序5e4大样例A的飞快。

#include<cstdio>
#include<queue>
#include<algorithm>
#define FN "keys"

const int maxn=5000+5;
const int maxk=10000+5;
const int oo=0x3f3f3f3f;

int a[maxn],b[maxk];

int abs(int x) {return x<0?-x:x;}

int main() {
    freopen(FN".in","r",stdin);
    freopen(FN".out","w",stdout);
    int n,k,p;scanf("%d%d%d",&n,&k,&p);
    for(int i=1;i<=n;i++) scanf("%d",a+i);
    for(int i=1;i<=k;i++) scanf("%d",b+i);
    std::sort(a+1,a+n+1),std::sort(b+1,b+k+1);
    int ans=oo;
    for(int i=1;i+n<=k;i++) {
        int temp=0;
        for(int j=0;j<n;j++)
            temp=std::max(temp,abs(b[i+j]-a[j+1])+abs(b[i+j]-p));
        ans=std::min(ans,temp);
    }
    printf("%d",ans);
    return 0;
}

cards

模拟题,用数据结构加速即可。

以上idy002原话。

先来杀比30分做法

抽牌,看牌,洗回去,满满的的queue。

最小值,会变,满满的priority_queue。

30分GET!

100分,掏出树状数组,接上vector,瞎搞搞,完事。

#include<cstdio>
#include<vector>
#include<algorithm>
#define FN "cards"
#define lowbit(i) i&(-i)
const int maxn=1e5+5;

int dit[maxn],n,val[maxn],vmax;
long long ans;
std::vector<int> vc[maxn];

void add(int pos,int delta) {
    for(int i=1;i<=n+1;i+=lowbit(i))
        dit[i]+=delta;
}

int query(int pos) {
    int rt=0;
    for(int i=pos;i;i-=lowbit(i))
        rt+=dit[i];
    return rt;
}

int query(int l,int r) {return query(r)-query(l-1);}

int clac(int x,int y) {
    if(x<=y) return query(x,y);
    else return query(x,n)+query(1,y);
}

int main() {
    freopen(FN".in","r",stdin);
    freopen(FN".out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d",val+i);
        vc[val[i]].push_back(i);
        vmax=std::max(vmax,val[i]);
    }
    n++;
    for(int i=1;i<=n-1;i++) add(i,1);
    int now=n;
    for(int i=1;i<=vmax;i++) {
        if(vc[i].empty()) continue;
        int pos=int(std::upper_bound(vc[i].begin(),vc[i].end(),now)-vc[i].begin());
        for(int k=pos;k<(int)vc[i].size();k++) {
            ans+=clac(now,vc[i][k]);
            add(vc[i][k],-1);
            now=vc[i][k];
        }
        for(int k=0;k<pos;k++) {
            ans+=clac(now,vc[i][k]);
            add(vc[i][k],-1);
            now=vc[i][k];
        }
    }
    printf("%I64d",ans);
}

bamboo

整除分块。

本来是a_maxn级别的,可以变成sqrt(a_max)n,就偷税的解决了。

其实主要因为整除分块昨天晚上才讲过。

#include <bits/stdc++.h>
using namespace std;

const int N = 111;

int n;
long long k;
vector<long long> vc;
long long aa[N];

void split( long long a, vector<long long> &vc ) {
    for( long long d = 1, dd; ; d = dd + 1 ) {
        long long k = (a + d - 1) / d;
        if( k <= 1 ) break;
        dd = (a + k - 1 - 1) / (k - 1) - 1;
        vc.push_back(d);
    }
    vc.push_back(a);
}
bool check( long long d ) {
    long long sum = 0;
    for( int i = 1; i <= n; i++ ) {
        sum += (aa[i] + d - 1) / d * d - aa[i];
    }
    return sum <= k;
}
int main() {
    freopen("bamboo.in", "r", stdin);
    freopen("bamboo.out", "w", stdout);
    scanf("%d%lld", &n, &k );
    for( int i = 1; i <= n; i++ ) {
        scanf("%lld", aa + i );
        split(aa[i],vc);
    }
    sort( vc.begin(), vc.end() );
    vc.erase(unique(vc.begin(),vc.end()),vc.end());
    vc.push_back( 10000000000000ll );
    long long ans = 1;
    for( int t = 0; t + 1 < (int)vc.size(); t++ ) {
        long long lf = vc[t];
        long long rg = vc[t+1] - 1;
        if( check(lf) == false ) continue;
        while( lf < rg ) {
            long long mid = (lf + rg + 1) >> 1;
            if( check(mid) )
                lf = mid;
            else
                rg = mid - 1;
        }
        ans = max( ans, lf );
    }
    printf( "%lld\n", ans );
}

总结(讲垃圾话)

T1贪错了。
其余暴力。
万事休矣。

放假了,人凉了。

27号和林荫dalao一起考试,有点方。

好好回家A解密实验室吧!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!