NOIP2007提高组

2007提高
A.统计数字(模拟)
B.字符串的展开(模拟)
C.矩阵取数游戏(dp+高精度)
考虑倒着dp,dp[i][j]表示还剩i…j的数,把这些取走的最大得分。决策无非两种,先拿i,先拿J.
D. 树网的核(树的直径+贪心+暴力枚举)
n=300,各种瞎搞。如果只能选一个点的话,一定选中心最优,因此我们以中心为根,贪心的去扩展。每次看能不能把最远的点干掉。。不能时就是答案了。

A

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 200010
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,a[N],ans[N],cnt[N],num=0;
int main(){
//  freopen("a.in","r",stdin);
    n=read();for(int i=1;i<=n;++i) a[i]=read();sort(a+1,a+n+1);a[0]=-1;
    for(int i=1;i<=n;++i){
        if(a[i]!=a[i-1]) ans[++num]=a[i],cnt[num]=1;
        else cnt[num]++;
    }for(int i=1;i<=num;++i) printf("%d %d\n",ans[i],cnt[i]);
    return 0;
}

B

#include<cstdio>
#include<cstring>
int p1,p2,p3,k=0;
char str[101],ans[10000];
void work(int x,int y){
    int p=0;
    if(x>='a'&&x<='z'&&y>='a'&&y<='z') p=1;
    if(x>='0'&&x<='9'&&y>='0'&&y<='9') p=2;
    if(!p||x>=y){ans[++k]='-';return;}
    if(x+1==y) return;
    if(p3==1){
        if(p1==1||(p1==2&&p==2))
            for(int i=x+1;i<y;++i)
                for(int j=1;j<=p2;++j) ans[++k]=i;
        if(p1==2&&p==1)
            for(int i=x-32+1;i<y-32;++i)
                for(int j=1;j<=p2;++j) ans[++k]=i;
        if(p1==3)
            for(int i=x+1;i<y;++i)
                for(int j=1;j<=p2;++j) ans[++k]='*';
    }else{
        if(p1==1||(p1==2&&p==2))
            for(int i=y-1;i>x;--i)
                for(int j=1;j<=p2;++j) ans[++k]=i;
        if(p1==2&&p==1)
            for(int i=y-32-1;i>x-32;--i)
                for(int j=1;j<=p2;++j) ans[++k]=i;
        if(p1==3)
            for(int i=y-1;i>x;--i)
                for(int j=1;j<=p2;++j) ans[++k]='*';
    }
}
int main(){
    //freopen("a.in","r",stdin);
    scanf("%d%d%d%s",&p1,&p2,&p3,&str);
    for(int j=0;str[j]!=0;++j)
        if(str[j]=='-') work(str[j-1],str[j+1]);
        else ans[++k]=str[j];
    printf("%s",ans+1);
    return 0;
}

C

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,m,w[N];
struct bigint{
    int a[50],n;
    bigint(){memset(a,0,sizeof(a));n=0;}
    friend bigint operator+(bigint x,bigint y){
        bigint res;res.n=max(x.n,y.n);
        for(int i=1;i<=res.n;++i) res.a[i]=x.a[i]+y.a[i];
        for(int i=1;i<=res.n;++i) res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
        if(res.a[res.n+1]) res.n++;return res;
    }
    friend bigint operator*(bigint x,int y){
        bigint res;res.n=x.n;
        for(int i=1;i<=res.n;++i) res.a[i]=x.a[i]*y;
        for(int i=1;i<=res.n;++i) res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
        while(res.a[res.n+1]) res.n++,res.a[res.n+1]+=res.a[res.n]/10,res.a[res.n]%=10;
        return res;
    }
}ans,bin[N];
inline bigint max(bigint x,bigint y){
    if(x.n>y.n) return x;if(x.n<y.n) return y;
    for(int i=x.n;i>=1;--i){
        if(x.a[i]>y.a[i]) return x;
        if(x.a[i]<y.a[i]) return y;
    }return x;
}
int main(){
//  freopen("a.in","r",stdin);
    m=read();n=read();bin[0].a[1]=1;bin[0].n=1;
    for(int i=1;i<=80;++i) bin[i]=bin[i-1]*2;
    while(m--){
        for(int i=1;i<=n;++i) w[i]=read();bigint dp[N][N];
        for(int i=1;i<=n;++i) dp[i][i]=bin[n]*w[i];
        for(int len=2;len<=n;++len)
            for(int i=1;i+len-1<=n;++i){
                int j=i+len-1;
                dp[i][j]=max(dp[i+1][j]+bin[n-len+1]*w[i],dp[i][j-1]+bin[n-len+1]*w[j]);
            }ans=ans+dp[1][n];
    }for(int i=ans.n;i>=1;--i) putchar(ans.a[i]+'0');return 0;
}

D

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 310
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,s,h[N],num=0,dis[N],fa[N],dep[N],res=1,rt=1,d=0,len=0,du[N];
bool inq[N];
struct edge{
    int to,next,val;
}data[N<<1];
void dfs(int x){
    for(int i=h[x];i;i=data[i].next){
        int y=data[i].to;if(fa[x]==y) continue;
        fa[y]=x;dis[y]=dis[x]+data[i].val;
        if(dis[y]>dis[res]) res=y;dfs(y);
    }
}
void dfs1(int x){
    for(int i=h[x];i;i=data[i].next){
        int y=data[i].to;if(fa[x]==y) continue;
        fa[y]=x;dis[y]=dis[x]+data[i].val;dep[y]=dep[x]+1;
        if(dis[y]>dis[res]) res=y;dfs1(y);
    }
}
void dfs2(int x){
    for(int i=h[x];i;i=data[i].next){
        int y=data[i].to;if(fa[x]==y) continue;
        dis[y]=dis[x]+data[i].val;dfs2(y);
    }
}
int main(){
//  freopen("a.in","r",stdin);
    n=read();s=read();
    for(int i=1;i<n;++i){
        int x=read(),y=read(),val=read();
        data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].val=val;
        data[++num].to=x;data[num].next=h[y];h[y]=num;data[num].val=val;
    }dfs(1);rt=res;fa[rt]=0;dis[rt]=0;dfs(rt);d=dis[res];
    //如果只能选一个点的话,一定选中心最优,因此我们以中心为根,贪心的去扩展 
    while(res!=rt){if(dis[fa[res]]<=d/2) break;res=fa[res];}
    int dx=dis[res]-d/2,dy=d/2-dis[fa[res]];if(dx<=dy) rt=res;else rt=fa[res];
    fa[rt]=0;dis[rt]=0;res=rt;inq[res]=1;du[res]=0;dfs1(rt);
    while(1){
        for(int i=1;i<=n;++i) if(dis[i]>dis[res]) res=i;
        int ans=dis[res];if(!ans){puts("0");return 0;}
        while(!inq[fa[res]]) res=fa[res];
        if((fa[res]==rt?du[fa[res]]>=2:du[fa[res]]>=1)||len+dis[res]>s){printf("%d\n",ans);return 0;}
        du[fa[res]]++;inq[res]=1;len+=dis[res];dis[res]=0;dfs2(res);
    }return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值