ACM-9月24日周日周末训练心得

    这周又是两场网络赛,周六的北京赛区实在是战况惨烈,只出了第一道题,签了个到,第一题是我写的= =,队友们全部卡在后面的题目了,第一题大致的意思就是小明旅游n天有m天呆在北京,m天中的第一天去北大,剩下的天里再找一天去北大,然而每天在北大排队的人数不同,求总排队人数最少的天,而且有些天是交通管制哪里都不能去,所以要花k天在北京减去交通管制的天数正好是m天,我的做法就是用循环去遍历,交通管制的那天我自动将排队人数变成-1处理。

 

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int n,m,q,r,min,resr,resl,cnt;
    int p[100];
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        min=2001;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&p[i]);
        }
        scanf("%d",&q);
        for(int i=0;i<q;i++)
        {
            scanf("%d",&r);
            p[r]=-1;
        }
        for(int k=m;k<=n;k++)
        {
            for(int i=0;i<=n-k;i++)
            {
                cnt=0;
                if(p[i]==-1)continue;
                for(int j=i+1;j<=i+k-1;j++)
                {
                    if(p[j]==-1)cnt++;
                }
                if(k-cnt==m)
                {
                   for(int j=i+1;j<=i+k-1;j++)
                    {
                        if(p[i]+p[j]<=min&&p[j]!=-1){min=p[i]+p[j];resr=i;resl=j;}
                    }
                }
                else continue;
            }
        }
        printf("%d %d\n",resr,resl);
    }
}

    然后今天的南宁赛区的网络赛,A了两道题,怎么说呢,线段树和树状数组如果再看的多一点的话可能能写更多,在此,谴责自己。

 

    A的第一道题是B,这道题算的是列车上最大的乘客位数,一开始用的线段树,由于对更新线段树的掌握还不是很透彻,发现把问题想复杂了,最后改为暴力就过了

 

#include<string.h>
#include<math.h>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    int x;
    int val;
    int cnt;
}a[2005];
bool cmp(node qq,node ww)
{
    if(qq.x==ww.x)
    {
        return qq.cnt>ww.cnt;
    }
    return qq.x<ww.x;
}
int main()
{
    int n;
    while(scanf("%d",&n))
    {
        if(n==0) {cout<<"*"<<endl;break;}
        int o=0;
        for(int i=1;i<=n;i++)
        {
            int h,h1,h2;
            scanf("%d%d%d",&h1,&h2,&h);
            if(h1>h2) swap(h1,h2);
            if(h1==h2) continue;
            a[++o].x=h1;
            a[o].val=h;
            a[o].cnt=1;

            a[++o].x=h2-1;
            a[o].val=h;
            a[o].cnt=-1;
        }
        sort(a+1,a+o+1,cmp);
        int sum=0,ans=0;
        for(int i=1;i<=o;i++)
        {
            if(a[i].cnt==1) sum+=a[i].val;
            if(a[i].cnt==-1) sum-=a[i].val;
            if(sum>ans) ans=sum;
        }
        cout<<ans<<endl;
    }
}

    第二个是完全套用的线段树扫描的模板,极其类似,然后就过了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=10005;
#define lson i*2,l,m
#define rson i*2+1,m+1,r
#define root 1,1,k-1
int X[MAXN];
struct node
{
    int l,r,h;
    int d;
    node(){}
    node(int a,int b,int c,int d): l(a),r(b),h(c),d(d){}
    bool operator <(const node &b)const
    {
        return h<b.h;
    }
}nodes[MAXN];
int cnt[MAXN*4];
int sum[MAXN*4];
void PushDown(int i,int l,int r)
{
    int m=(l+r)/2;
    if(cnt[i]!=-1)
    {
        cnt[i*2]=cnt[i*2+1]=cnt[i];
        sum[i*2]= (cnt[i]?(X[m+1]-X[l]):0) ;
        sum[i*2+1]= (cnt[i]?(X[r+1]-X[m+1]):0) ;
    }
}
void PushUp(int i,int l,int r)
{
    if(cnt[i*2]==-1 || cnt[i*2+1]==-1)
        cnt[i]=-1;
    else if(cnt[i*2]!= cnt[i*2+1])
        cnt[i]=-1;
    else
        cnt[i]=cnt[i*2];
    sum[i]=sum[i*2]+sum[i*2+1];
}
void build(int i,int l,int r)
{
    if(l==r)
    {
        cnt[i]=0;
        sum[i]=0;
        return ;
    }
    int m=(l+r)/2;
    build(lson);
    build(rson);
    PushUp(i,l,r);
}
void update(int ql,int qr,int v,int i,int l,int r)
{
    if(ql<=l && r<=qr)
    {
        if(cnt[i]!=-1)
        {
            cnt[i]+=v;
            sum[i] = (cnt[i]? (X[r+1]-X[l]):0);
            return ;
        }
    }
    PushDown(i,l,r);
    int m=(l+r)/2;
    if(ql<=m) update(ql,qr,v,lson);
    if(m<qr) update(ql,qr,v,rson);
    PushUp(i,l,r);
}
int bin(int key,int n,int d[])
{
    int l=1,r=n;
    while(r>=l)
    {
        int m=(r+l)/2;
        if(d[m]==key)
            return m;
        else if(d[m]>key)
            r=m-1;
        else
            l=m+1;
    }
    return -1;
}
int main()
{
    int q;
    int kase=0;
    while(scanf("%d",&q))
    {
        if(q==0){cout<<"*"<<endl;break;}
        int n=0,m=0;
        for(int i=1;i<=q;i++)
        {
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            X[++n]=x1;
            nodes[++m]=node(x1,x2,y1,1);
            X[++n]=x2;
            nodes[++m]=node(x1,x2,y2,-1);
        }
        sort(X+1,X+n+1);
        sort(nodes+1,nodes+m+1);
        int k=1;//共k个不同的x坐标,组成了k-1个不同的区域
        for(int i=2;i<=n;i++)
            if(X[i]!=X[i-1]) X[++k]=X[i];
        build(1,1,k-1);//少了build就WA
        int ret=0;//最终面积
        for(int i=1;i<m;i++)
        {
            int l=bin(nodes[i].l,k,X);
            int r=bin(nodes[i].r,k,X)-1;
            if(l<=r) update(l,r,nodes[i].d,root);
            ret += sum[1]*(nodes[i+1].h-nodes[i].h);
        }
        cout<<ret<<endl;
    }
}

    比较可惜的是第L题,用的动态规划,求最重的上升子序列,最后是以内存超了为结束,想不到如何解决。

 

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<cmath>
#include<vector>
using namespace std;
int main()
{
    int dp[200001],c,maxw,q=0;
    char l;
    vector<int> a,w;
    while(scanf("%d",&c))
    {
        if(c<0)
        {
            a.push_back(c);
            w.push_back(0);
        }
        else if(c>=10000)
        {
            a.push_back(c-10000);
            w.push_back(5);
        }
        else
        {
            a.push_back(c);
            w.push_back(1);
        }
        l=getchar();
        if(l=='\n')break;
    }
    int n=a.size();
    //cout<<n<<endl<<endl;
    dp[0]=w[0];//表示以w[0]为子序列最右边的重量
    for (int i=1;i<n;i++)
    {
        dp[i]=w[i];
        for (int j=0;j<i;j++)
        {
            if (a[i]>=a[j]&&dp[j]+w[i]>dp[i])
                dp[i]=dp[j]+w[i];
        }
    }
    for(int i=maxw=0;i<n;i++)
    {
        maxw=max(maxw,dp[i]);
        //cout<<dp[i]<<endl;
    }
    cout<<maxw<<endl;
}

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后台采用apache服务器下的cgi处理c语言做微信小程序后台逻辑的脚本映射。PC端的服务器和客户端都是基于c语言写的。采用mysql数据库进行用户数据和聊天记录的存储。.zip C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值