• 第二关——2007NOIP提高组


    14:27:40 我习惯在包里藏一瓶百无聊赖,打发人间白云和苍狗设计睡着的未来。 ——《我的名字》焦迈奇

    有一种悲伤 叫做期末考试有什么大不了的,你怕什么,它就考什么

    期末考的差(划重点,要考),悲伤到连A+Bproblem都打不出来,就只好来写博客!!!

    第一题  统计数字

    http://219.153.61.2:9000/contest/239/problem/1076

    这道题很简单,我用的是sort函数进行排序,然后再输出的。

    悲伤到不能打字,话不多说放代码

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll n,a[200009];
    int main()
    {
        scanf("%d",&n);
        for(ll i=1;i<=n;i++)
        scanf("%d",&a[i]);
        sort(a,a+n+1);
        ll m=a[1],s=1;
        for(ll i=2;i<=n;i++)
        {
            if(a[i]==m)s++;
            else
            {
                cout<<m<<" "<<s<<endl;
                m=a[i],s=1;
            }
        }
        cout<<m<<" "<<s<<endl;
        return 0;
     } 

    14:51:10  江山如此多娇,引无数英雄竞折腰

    我太难了!!!

    第二题  字符串的展开   

    http://219.153.61.2:9000/contest/239/problem/1077

    题目简单易懂,代码思路简单。就是无限无限无限无限的if条件语句。(唉,成绩杀我)打的我真的是头晕转向。(唉)这道题虽然思路清晰明了,代码也简单,但是有许多许多许多许多细小的问题值得注意一下,要不然一个问题就会挖你10分20分的样子。(唉,期末什么期末,我不要放假,我不要成绩)

    • 注意开字符数组,不要看题目说的什么字符串就天真傻傻的去开个字符串,会超出范围,反正字符串跟字符数组差不多的用法。字符数组它不香吗,所以还是建议用字符数组。(专业手抖100年)(唉)!!!
    • if语句中的条件要写清楚,比如两边要同为小写或同为数字而且左边比右边小之类的,要理清楚什么时候是<,什么时候是>,什么时候该=。(唉,这点要注意,很重要)
    • p1决定字符形式,注意在p1=2时,小写转大写是只有小写才减的!!!数字不要剪,这里要加一个条件,而且再加条件之后要将if语句的位置调换一下(也可以在加条件的基础上再加一个条件),不然又会错一个点。

    好了,康康代码吧!!!(唉)

    #include<bits/stdc++.h>
    using
    namespace std; char a[1000000]; int p1,p2,p3; int main() { cin>>p1>>p2>>p3; cin>>a; for(int i=0;i<strlen(a);i++) { if(a[i]=='-'&&((a[i+1]>='0'&&a[i+1]<='9'&&a[i-1]>='0'&&a[i-1]<='9'&&a[i+1]>a[i-1])||(a[i+1]>='a'&&a[i+1]<='z'&&a[i-1]>='a'&&a[i-1]<='z'&&a[i+1]>a[i-1]))) { char s[1000000]; int o=0; for(int j=a[i-1]+1;j<a[i+1];j++) { if(p1==3) for(int k=1;k<=p2;k++) s[++o]='*'; else if(p1==1||(j>='0'&&j<='9')) for(int k=1;k<=p2;k++) s[++o]=j; else if(p1==2) for(int k=1;k<=p2;k++) s[++o]=j-32; } if(p3==1) for(int j=1;j<=o;j++) cout<<s[j]; else for(int j=o;j>=1;j--) cout<<s[j]; } else cout<<a[i]; } return 0; }

    15:40:44 害!!!

    命啊!!!

    第三题   矩阵取数游戏

    https://www.luogu.com.cn/problem/P1005

    这道题不能用简单的暴力做,如果这样做的话,只能得到20分。

    这道题实际上是一道dp的题。

    其次,因为数据极其的大,所以在比赛是打这道题的时候,只能使用高精度

    有一个n×m的矩阵,对于第ii行,每次取走边缘的Ai,j,增加这一行的得分x,求n行的最大得分总和。因为落实每一行,所以行之间的关系是不大的。

    fi,j=max{fi1,j+Ai1,j2mj+i1,fi,j+1+Ai,j+12mj+i1}

    Ans=maxim{fi,i+Ai,i2m}

    话不多说,上代码吧

    #include<bits/stdc++.h>
    #define ll __int128
    void print(ll x)
    {
        if (x==0) return;
        if (x)print(x/10);
        putchar(x%10+'0');
    }
    int n,m;
    ll ans,a[100],f[100][100],p[100]={1};
    ll dp()
    {
        memset(f,0,sizeof(f));
        for(int i=1;i<=m;i++)
        for(int j=m;j>=i;j--)
        f[i][j]=std::max(f[i-1][j]+p[m-j+i-1]*a[i-1],f[i][j+1]+p[m-j+i-1]*a[j+1]);
        ll maxn=-1;
        for(int i=1;i<=m;i++)
        maxn=std::max(maxn,f[i][i]+a[i]*p[m]);
        return maxn;
    }
    int main()
    {
        for(int i=1;i<=90;i++) 
        p[i]=p[i-1]<<1;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            scanf("%d",a+j);
            ans+=dp();
        }
        if(ans==0) puts("0");
        else print(ans);
        return 0;
    }

    以上为懒人算法,考试上是过不去的,好吧。(不要轻易模仿)

    以下为我后面那个大佬的高精度代码,感谢大佬给我版权。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=85,mod=10000;
    int n,m;
    int ar[N];
    
    struct node{
        int p[505], len;
        node() {
            memset(p, 0, sizeof p);
            len = 0;
        }  
        void print() {
            printf("%d", p[len]);  
            for (int i = len - 1; i > 0; i--) {  
                if (p[i] == 0) {
                    printf("0000"); 
                    continue;
                }
                for (int k = 10; k * p[i] < mod; k *= 10) 
                    printf("0");
                printf("%d", p[i]);
            }
        }
    }f[N][N],base[N],ans;
    
    node operator + (const node &a,const node &b){
        node c; c.len = max(a.len, b.len); int x = 0;
        for (int i = 1; i <= c.len; i++) {
            c.p[i] = a.p[i] + b.p[i] + x;
            x = c.p[i] / mod;
            c.p[i] %= mod;
        }
        if (x > 0)
            c.p[++c.len] = x;
        return c;
    }
    
    node operator * (const node &a,const int &b){
        node c; c.len = a.len; int x = 0;
        for (int i = 1; i <= c.len; i++) {
            c.p[i] = a.p[i] * b + x;
            x = c.p[i] / mod;
            c.p[i] %= mod;
        }
        while (x > 0)
            c.p[++c.len] = x % mod, x /= mod;
        return c;
    }
    node max(const node &a,const node &b){
        if (a.len > b.len)
            return a;
        else if (a.len < b.len)
            return b;
        for (int i = a.len; i > 0; i--)
            if (a.p[i] > b.p[i])
                return a;
            else if (a.p[i] < b.p[i])
                return b;
        return a;
    }
    
    inline void basetwo(){
        base[0].p[1]=1,base[0].len=1;
        for(int i=1;i<=m+2;i++){
            base[i]=base[i-1]*2;
        }
    }
    
    inline int read(){
        int p=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)) f*=(ch=='-')? -1:1,ch=getchar();
        do p=(p<<1)+(p<<3)+(ch^48),ch=getchar();
        while(isdigit(ch));
        return p*f;
    }
    
    int main(){
        n=read(),m=read();
        basetwo();
        while(n--){
            memset(f,0,sizeof f);
            for(int i=1;i<=m;i++) ar[i]=read();
            for(int i=1;i<=m;i++){
                for(int j=m;j>=i;j--){
                    f[i][j] = max(f[i][j], f[i - 1][j] + base[m - j + i - 1] * ar[i - 1]); 
                    f[i][j] = max(f[i][j], f[i][j + 1] + base[m - j + i - 1] * ar[j + 1]);
                }
            }
            node Max;
            for (int i = 1; i <= m; i++)
                Max = max(Max, f[i][i] + base[m] * ar[i]);
            ans = ans + Max; 
        }
        ans.print();
        return 0;
    }

    15:19:20 生亦我所欲也,死亦我所欲也(小朋友不要盲目背这句话哦)

    暴风哭泣!!!

    第四题   树网的核

    http://219.153.61.2:9000/contest/239/problem/1079

    这道题是关于树的!!!唉,学信奥=洗脑=“树学竞赛”

    首先,有几个概念要搞清楚

    路径:树网中任何两结点a,b都存在唯一的一条简单路径,用d(a,b)表示以a,b为端点的路径的长度,它是该路径上各边长度之和。我们称d(a, b)a,b两结点间的距离。

    D(v,P)=min{d(v,u)}, u为路径P上的结点。

    树网的直径:树网中最长的路径成为树网的直径。对于给定的树网TT,直径不一定是唯一的,但可以证明:各直径的中点(不一定恰好是某个结点,可能在某条边的内部)是唯一的,我们称该点为树网的中心。

    偏心距ECC(F):树网T中距路径F最远的结点到路径FF的距离,即

    ECC(F)=max{d(v,F),vV}

    因为树方面的题主要是背模板,所以就直接上代码了。(唉)!!!

    #include<bits/stdc++.h>
    using namespace std;
    int top,n,s,head[100010],vet[100010],val[100010],nex[100010],a[100010],fa[100010],dis[100010];
    bool f[100010];
    void add(int u,int v,int c)
    {
        nex[++top]=head[u];
        head[u]=top;
        vet[top]=v;
        val[top]=c;
    }
    void dfs(int u,int x)
    {
        int e,v;
        for (e=head[u];v=vet[e],e;e=nex[e])
        if (v!=x)
        {
            fa[v]=u;
            dis[v]=dis[u]+val[e];
            dfs(v,u);
        }
    }
    void sy(int u,int x,int y)
    {
        int e,v;
        for (e=head[u];v=vet[e],e;e=nex[e])
        if (v!=x&&!f[v])
        {
            a[y]=max(a[y],dis[v]-dis[u]);
            sy(v,u,y);
        }
    }
    int main()
    {
        int x,y,z;
        scanf("%d%d",&n,&s);
        for (int i=1; i<n; i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z),add(y,x,z);
        }
        dfs(1,0);
        int l=0,r=0;
        for (int i=1;i<=n;i++)
        if (dis[i]>dis[l])
        l=i;
        for (int i=1;i<=n;i++) 
        dis[i]=0;
        dfs(l,0);
        for(int i=1;i<=n;i++)
        if(dis[i]>dis[r]) 
        r=i;//两次dfs求直径
        fa[l]=0;//注意一定要把根的父亲重置为0,因为在第一次dfs中它是一个结点
        for (int i=r;i;i=fa[i])
        f[i]=1;
        for (int i=r;i;i=fa[i])
        sy(i,0,i);
        int ans=0,ss=9999999;
        for (int i=r;i;i=fa[i])
            for (int j=i;j;j=fa[j])
            {
                if(dis[i]-dis[j]>s)break;//优化
                ans=max(dis[j],dis[r]-dis[i]);//特殊点
                for (int k=i; k!=fa[j]; k=fa[k])
                ans=max(ans,a[k]);
                ss=min(ans,ss);
            }
        printf("%d
    ",ss);
        return 0;
    }

    15:36:02煎熬,时间在这一刻停止了吗,过得好漫长啊,害!!!何时才能解脱

  • 相关阅读:
    C++输入问题探究
    剑指offer自学系列(一)
    一道算法题加深我对C++中map函数的理解
    数据结构和算法自学之排序算法(一)
    pyqt5_01_流程走通
    最新谷歌驱动对照表
    移动端测试
    selenium封装
    request封装
    MD5自定义加密
  • 原文地址:https://www.cnblogs.com/wybxz/p/12206211.html
Copyright © 2020-2023  润新知