noip模拟66[依旧很菜]

noip模拟66 solutions

话说这几次一直改不完题,今天也只是改了三道题

只能先咕掉,以后再改了。。

今天的考试,时间分配极其不好,还有一个就是我思想的问题

做到最后发现啥也不会,然后就不想做了,导致我直接交了前两个题就走人了

以后一定要做完题,要不然会非常后悔的

T1 接力比赛

这个我知道是个背包,但是我直接干了个裸的上去,一点优化都没带

然后导致我没有切掉,,,

下次遇见题一定要记得优化暴力

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1005;
const int M=1e6;
int n,m,tot,ans;
int wn[N],vn[N],sn[N];
int wm[N],vm[N],sm[N];
int f[M],g[M];
signed main(){
    #ifdef oj
        freopen("game.in","r",stdin);
        freopen("game.out","w",stdout);
    #endif
    scanf("%lld%lld",&n,&m);
    fo(i,1,n)scanf("%lld%lld",&wn[i],&vn[i]),sn[i]=sn[i-1]+wn[i];
    fo(i,1,m)scanf("%lld%lld",&wm[i],&vm[i]),sm[i]=sm[i-1]+wm[i];
    memset(f,-0x3f,sizeof(f));f[0]=0;
    memset(g,-0x3f,sizeof(g));g[0]=0;
    fo(i,1,n)fu(j,sn[i],wn[i])f[j]=max(f[j],f[j-wn[i]]+vn[i]);
    fo(i,1,m)fu(j,sm[i],wm[i])g[j]=max(g[j],g[j-wm[i]]+vm[i]);
    fo(i,1,min(sn[n],sm[m]))ans=max(ans,f[i]+g[i]);
    printf("%lld",ans);
}

T2 树上竞技

这个题太妙了,那个组合数!!!

其实对于许多组合数来说,当你给他赋予一个实际含义的时候,

如果需要递推,或者需要求和,这样就会变得很简单

所以要不断地积累一些例子,让在考场上应用组合数的时候更加得心应手

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
const int mod=1e9+7;
int n,m;
int to[N*2],nxt[N*2],head[N],rp;
void add_edg(int x,int y){
    to[++rp]=y;
    nxt[rp]=head[x];
    head[x]=rp;
}
int g[N],jc[N],inv[N];
int ksm(int x,int y){
    int ret=1;
    while(y){
        if(y&1)ret=ret*x%mod;
        x=x*x%mod;y>>=1;
    }return ret;
}
int C(int x,int y){if(x<y)return 0;return jc[x]*inv[y]%mod*inv[x-y]%mod;}
int siz[N],ans;
void dfs(int x,int f){
    siz[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y==f)continue;
        dfs(y,x);siz[x]+=siz[y];
    }
    ans=(ans+g[siz[x]]+g[n-siz[x]])%mod;
    if(m%2==0)ans=(ans+C(siz[x],m/2)*C(n-siz[x],m/2)%mod*(m/2)%mod)%mod;
}
signed main(){
    #ifdef oj
        freopen("meeting.in","r",stdin);
        freopen("meeting.out","w",stdout);
    #endif
    scanf("%lld%lld",&n,&m);
    fo(i,2,n){
        int x;scanf("%lld",&x);
        add_edg(i,x);add_edg(x,i);
    }
    jc[0]=1;fo(i,1,n)jc[i]=jc[i-1]*i%mod;
    inv[0]=1;inv[n]=ksm(jc[n],mod-2);
    fu(i,n-1,1)inv[i]=inv[i+1]*(i+1)%mod;
    if(m>2)g[1]=C(n-1,m-1);
    fo(i,1,n-1)g[i+1]=(g[i]+mod-C(i-1,(m-1)/2-1)*C(n-i-1,m-(m-1)/2-1)%mod)%mod;
    fo(i,1,n)g[i]=g[i]*i%mod;
    dfs(1,0);printf("%lld",ans);
}

T3 虚构推理

有一点点小小的后悔。

这道题我考场上看到非常的麻烦,就直接跳过了

但是后来一看好像还挺简单的,暴力分还是挺好拿的

我没有打正解,直接在时间复杂度可以接受的范围内枚举的

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=50005;
int n,ah,am,as;
double h[N],m[N],ans=1000000000.0;
void sol(double i,double j,double k){
    double th=i*30.0+j*0.5+k*0.5/60.0;
    double tm=j*6.0+k*0.1;
    if(th>=180.0)th-=180.0;
    else th+=180.0;
    if(tm>=180.0)tm-=180.0;
    else tm+=180.0;
    int ph=upper_bound(h+1,h+n+1,th)-h-1;
    int pm=upper_bound(m+1,m+n+1,tm)-m-1;
    double r1=180.0-th+h[ph];if(r1<0)r1+=360.0;if(r1>=360.0)r1-=360.0;
    double r2=180.0-h[ph+1]+th;if(r2<0)r2+=360.0;if(r2>=360.0)r2-=360.0;
    double r3=180.0-tm+m[pm];if(r3<0)r3+=360.0;if(r3>=360.0)r3-=360.0;
    double r4=180.0-m[pm+1]+tm;if(r4<0)r4+=360.0;if(r4>=360.0)r4-=360.0;
    if(360.0-r1<r1)r1=360.0-r1;
    if(360.0-r3<r3)r3=360.0-r3;
    ans=min(ans,max(max(r1,r2),max(r3,r4)));
}
signed main(){
    #ifdef oj
        freopen("unreal.in","r",stdin);
        freopen("unreal.out","w",stdout);
    #endif
    scanf("%d",&n);
    fo(i,1,n){
        scanf("%d",&ah);getchar();
        scanf("%d",&am);getchar();
        scanf("%d",&as);getchar();ah%=12;
        //cout<<ah<<":"<<am<<":"<<as<<endl;
        h[i]=ah*30.0+am*0.5+as*0.5/60.0;
        m[i]=am*6.0+as*0.1;
    }
    sort(h+1,h+n+1);h[0]=h[n];h[n+1]=h[1];
    sort(m+1,m+n+1);m[0]=m[n];m[n+1]=m[1];
    fo(i,0,11)fo(j,0,59)for(double k=0;k<60;k+=0.01)sol(i,j,k);
    printf("%.10lf",ans);
}

T4 记忆碎片

我还没有改

上一篇:多校冲刺 noip 10.30


下一篇:noip模拟77[loss]