2018年7月17日暑假训练日记

  早上有些蒙......住的地方没灯光,醒了还以为还早,结果已然九点半

  今天继续接受阻力,在规律题:1013 Buildings上卡了一段时间,虽说感觉说的出来,但是却又难于言表,最后找到了两个制约条件,漏掉了在中间和长短条的特殊处理,还是理解不够深刻。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
    long long n,m,x,y;
    while (scanf("%lld%lld%lld%lld",&n,&m,&x,&y)!=EOF){
        if (n>m){
            swap(n,m);
            swap(x,y);
        }
        if (n==m&&n%2&&x==y&&x==(n+1)/2){
            printf("%lld\n",m/2);
        }
        else {
            long long ans=(n+1)/2;
            x=min(x,n-x+1);
            y=min(y,m-y+1);
            ans=max(ans,min(y,n-x));
            printf("%lld\n",ans);
        }
    }
}
  然后想了一下1009 Y sequence的容斥,但是发现还有个迭代加速法,题解的二分也超时了,于是灵光一现,把我昨天的代码改成了迭代,结果wr了,突然知道了容斥在哪里,因为有的数既可以是4次方又可以是2次方,这样在处理的时候就会漏掉很多,但是样例很小就很容易通过。于是加以交叉项的容斥过之。一是亏在想法少,二是失败在见得少。

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#define maxn 100010
using namespace std;
long long prime[19]={-2,-3,-5,-7,-11,-13,-17,-19,-23,-29,-31,-37,-41,-43,-47,-53,-59,-61,-67};
vector<long long>p;
void getp(long long r){
    long long i,j;
    p.clear();
    for (i=0;abs(prime[i])<=r;i++){
        long long temp=p.size();
        for (j=0;j<temp;j++){
            if (abs(prime[i]*p[j])<=63){
                p.push_back(prime[i]*p[j]);
            }
        }
        p.push_back(prime[i]);
    }
}
long long cal(long long x){
    if (x==1)return 0;
    long long ans=x;
    long long i,j;
    for (i=0;i<p.size();i++){
        long long temp=(long long)(pow(x+0.5,1.0/abs(p[i])))-1;
        if(p[i]<0){
            ans-=temp;
        }
        else{
            ans+=temp;
        }
    }
    return ans-1;
}
long long solve(long long x,long long y){
    long long ans=x;
    getp(y);
    while (true){
        long long temp=cal(ans);
        if (temp==x)break;
        ans+=x-temp;
    }
    return ans;
}
int main(){
    long long t,n,r;
    long long i,j,k,l,ans;
    scanf("%lld",&t);
    while (t--){
        scanf("%lld%lld",&n,&k);
        long long ans=solve(n,k);
        printf("%lld\n",ans);
    }
}
中午被老师叫过去当苦力,核对了一中午成绩,下午略为困倦,做了一个贪心的思维题目(其实是个细节题目)1015 Delicious Apples,主要的难点是:ai≥1,a1+a2+...+an≤105,由于苹果很少,所以可以进行离散处理,存每个苹果的位置,之后就简单了。

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#define maxn 100010
using namespace std;
long long a[maxn];
long long l[maxn],r[maxn];
long long dpl[maxn],dpr[maxn];
int main(){
    long long t;
    long long n,m,k,i,j,x,y,lcnt,rcnt;
    scanf("%lld",&t);
    while (t--){
        scanf("%lld%lld%lld",&k,&n,&m);
        long long cnt=0;
        while (n--){
            scanf("%lld%lld",&x,&y);
            for (i=1;i<=y;i++){
                a[++cnt]=x;
            }
        }
        lcnt=rcnt=0;
        for (i=1;i<=cnt;i++){
            if (a[i]<=k/2){
                l[++lcnt]=a[i];
            }
            else {
                r[++rcnt]=k-a[i];
            }
        }
        sort(l+1,l+lcnt+1);
        sort(r+1,r+rcnt+1);
        memset (dpl,0,sizeof(dpl));
        memset (dpr,0,sizeof(dpr));
        for (i=1;i<=lcnt;i++){
            if (i<=m)dpl[i]=l[i];
            else dpl[i]=dpl[i-m]+l[i];
        }
        for (i=1;i<=rcnt;i++){
            if (i<=m)dpr[i]=r[i];
            else dpr[i]=dpr[i-m]+r[i];
        }
        long long ans=2*(dpl[lcnt]+dpr[rcnt]);
        for (i=0;i<=min(lcnt,m);i++){
            j=max((long long)0,rcnt-(m-i));
            ans=min(ans,2*(dpl[lcnt-i]+dpr[j])+k);
        }
        printf("%lld\n",ans);
    }
}
 

猜你喜欢

转载自blog.csdn.net/m0_37772713/article/details/81087031