兰州大学程序设计比赛反思

 

题目描述

    ACM大家庭有n个同学。对于每个同学,都有对应的ACM能力值a[i](1<=i<=n)。当有两个同学的ACM能力值相差不超过k时,他们互为对方的ACM互助伙伴。请问一下ACM大家庭里有多少对ACM互助伙伴((A,B),(B,A)被视为同一对)。

输入描述:

第1行输入两个整数n,k(n<=100000)。本题限制k<=1。提示,k可以为0。

第2行输入n个整数,为a[1]~a[n](0<=a[i]<=1000000,1<=i<=n)。

提示: 互助伙伴:两人的能力值是很接近的。

输出描述:

输出一行,代表ACM互助伙伴对的数目。
反思:要关注时间复杂度,查找重视二分查找
/**
 * 二分查找,找到该值在数组中的下标,否则为-1
 */
static int binarySerach(int[] array, int key) {
    int left = 0;
    int right = array.length - 1;

    // 这里必须是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] == key) {
            return mid;
        }
        else if (array[mid] < key) {
            left = mid + 1;
        }
        else {
            right = mid - 1;
        }
    }

    return -1;
}

 

#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    int n,m,k,i,j,l,r,sum=0;
 
    scanf("%d %d",&n,&k);
    getchar();
    int ki[n],money[n];
    for(i=0;i<n;i++){
 
        scanf("%d",&ki[i]);
        getchar();
    }
    sort(ki,ki+n);
    for(i=0;i<n;i++)
    {
        l=i+1;
        r=n-1;
       while(l<=r)
       {
           j=(l+r)/2;
           if(ki[j]-ki[i]<=k)
           {
               l=j+1;
           }
           else{
            r=j-1;
           }
       }
       sum+=l-1-i;
    }
cout<<sum;
    return 0;
}

链接:https://www.nowcoder.com/acm/contest/137/D
来源:牛客网

题目描述

给定一个串A,请求出LZU_ACM(A)的最大值。

函数LZU_ACM (X)遵循如下定义:

对于串X,若删去该串的若干个字符或任何字符都不删去(其它字符的相对位置不变),剩下的串为若干个连续的“ILOVELZUACM”,则剩下的串中“ILOVELZUACM”的数目为函数LZU_ACM (X)的其中一个值。

输入描述:

第1行输入字符串的长度L。数据保证串不为空。1<=L<=100000。

第2行输入字符串A。数据保证字符串A只包含大写字母。

输出描述:

 

输出一行,为LZU_ACM(A)的最大值。反思:这道题才是最痛心的,最开始没多想,用了一串if结合操作系统的信号量机制,用一串和条件变量表示信号,过不了又不想写新的,一直换各种结构,包括switch等等,后来想到可能超时,就换一种方法,原来只是两个字符数组的匹配问题。。。原始解法见下面,通过解法见最后

#include <bits/stdc++.h>
#include <math.h>
#include <string>
using namespace std;
 
 
int main()
{
    int n=0,m=0,k=0,i=0,j=0,t=0,p=0,q=0,b=0,a=0,c=0,d=0;
    long long sum=0;
    cin>>d;
    char l[100010];
   cin>>l;
    i=0;
    int flag=1;
    for(i=0;i<d;i++)
    {
        if(l[i]=='I'&&flag)
        {
            n=1;
            i++;
            flag=0;
        }
        if(l[i]=='L'&&n>0)
        {
           m=1;
           n=0;
           i++;
        }
        if(l[i]=='O'&&m>0)
        {
            k=1;
            m--;
            i++;
        }
        if(l[i]=='V'&&k>0)
        {
            j=1;
            k--;
            i++;
        }
        if(l[i]=='E'&&j>0)
        {
            t=1;
            j--;
            i++;
        }
        if(l[i]=='L'&&t>0)
        {
            p=1;
            t--;
            i++;
        }
        if(l[i]=='Z'&&p>0)
        {
            q=1;
            p--;
            i++;
        }
        if(l[i]=='U'&&q>0)
        {
            b=1;
            q--;
            i++;
        }
        if(l[i]=='A'&&b>0)
        {
            a=1;
            b--;
            i++;
        }
         if(l[i]=='C'&&a>0)
        {
            c=1;
            a--;
            i++;
        }
         if(l[i]=='M'&&c>0)
        {
            sum++;
            c--;
            i++;
            flag=1;
 
        }
 
    }
    printf("%lld",sum);
    return 0;
}

 

#include <bits/stdc++.h>
#include <math.h>
#include <string>
using namespace std;
 
 
int main()
{
    char a[]={'I','L','O','V','E','L','Z','U','A','C','M'};
    int d,i,j;
    long long sum=0;
    cin>>d;
    char l[d+1];
    cin>>l;
    j=0;
    for(i=0;i<d;i++)
    {
      if(a[j]==l[i])
      {
          j++;
      }
      if(j==11)
      {
          sum++;
          j=0;
      }
    }
    cout<<sum;
    return 0;
}

链接:https://www.nowcoder.com/acm/contest/137/G
来源:牛客网
 

题目描述

XXXX年XX月XX日,小g与与女朋友吵架之后,决定赠送礼物挽回这段感情。现在有n种商品可供小g选择,每个商品的价格为v[i],能够增加的好感度为c[i]。但是小g的资金有限,他只有m元,小g的女朋友的当前好感度为k,请问小g最多能够将女朋友的好感度提升到多少?

输入描述:

第一行,3个数,n,m,k;

接下来n行,每行2个数,分别是商品的价格v[i]与能够增加的好感度c[i]。商品最多只能购买一次。

输出描述:

一行,1个数,为最终的好感度k。

最开始直接dfs,超时

#include <bits/stdc++.h>

using namespace std;
int n,m,k;
const int maxn=1100;
int v[maxn],c[maxn];
int maxhaogan=0;
void dfs(int index,int summ,int sumhaogan)
{
    if(index==n)
    {
        if(summ<=m&&sumhaogan>maxhaogan)
        {
            maxhaogan=sumhaogan;
        }
        return;
    }
    dfs(index+1,summ+v[index],sumhaogan+c[index]);
    dfs(index+1,summ,sumhaogan);
}
int main()
{
    int i;
    cin>>n>>m>>k;
    for(i=0;i<n;i++)
    {
        cin>>v[i]>>c[i];
    }
    dfs(0,0,k);
    cout<<maxhaogan;
    return 0;
}

增加边界条件之后还是过不了,只好转动归

#include <bits/stdc++.h>

using namespace std;
int n,m,k;
const int maxn=11000;
int v[maxn],c[maxn];
int dp[maxn];
int maxhaogan=0;
void dfs(int index,int summ,int sumhaogan)
{
    if(index==n)
    {
        return;
    }

    dfs(index+1,summ,sumhaogan);
    if(summ+v[index]<=m)
    {
        dfs(index+1,summ+v[index],sumhaogan+c[index]);
        if(sumhaogan+c[index]>maxhaogan)
        {
            maxhaogan=sumhaogan+c[index];
        }
    }

}
int main()
{
    int i,j;
    cin>>n>>m>>k;
    for(i=0; i<n; i++)
    {
        cin>>v[i]>>c[i];
    }
    memset(dp,0,sizeof(dp));
    for(i=1; i<=n; i++)
    {
//        for(j=v[i];j<=m;j++)
//        {
//            dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+c[i-1]);
//        }
        for(j=m; j>=v[i-1]; j--)
        {
        dp[j]=max(dp[j],dp[j-v[i-1]]+c[i-1]);
        }
    }
    int maxnum=0;
    for(i=0;i<=m;i++)
    {
        if(dp[i]>maxnum)
        {
            maxnum=dp[i];
        }
    }
    cout<<maxnum+k;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值