贪心训练(划水1)

## 看电视
时间限制: 1 Sec 内存限制: 32 MB
题目描述
暑假到了,小明终于可以开心的看电视了。但是小明喜欢的节目太多了,他希望尽量多的看到完整的节目。
现在他把他喜欢的电视节目的转播时间表给你,你能帮他合理安排吗?
输入
输入包含多组测试数据。每组输入的第一行是一个整数n(n<=100),表示小明喜欢的节目的总数。
接下来n行,每行输入两个整数si和ei(1<=i<=n),表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。
当n=0时,输入结束。
输出
对于每组输入,输出能完整看到的电视节目的个数。
样例输入
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0
样例输出
5
题解

#include <stdio.h>
#include <stdlib.h>
/*结构体内容:定义一个电视节目
包含参数:end(节目结束时间),start (节目开始时间)
关于结构体的知识在本题后有补充*/
struct telev
{
    int end;
    int start;
} a[100];
/*cmp功能:C语言qsort函数的辅助函数,
返回值为 a-b升序排列,b-a降序排列
排序按end一序,start二序*/
int cmp ( const void *a , const void *b )
{
    return *(int *)a - *(int *)b;
}

int main(int argc,char* argv[])
{
    int i, n, c, t, j;
    while(scanf("%d", &n)!= EOF&&n!= 0)
    {
        for(i = 0; i < n; i++)
        {
            scanf("%d%d", &a[i].start, &a[i].end);
        }
//        for(i = 0; i < n; i++)
//        {
//            for(j = i; j < n; j++)
//            {
//                if(a[i].end > a[j].end)
//                {
//                    t = a[i].end;
//                    a[i].end = a[j].end;
//                    a[j].end = t;
//                    t = a[i].start;
//                    a[i].start = a[j].start;
//                    a[j].start = t;
//                }
//            }
//        }
/*上面的冒泡排序和qsort的功能一样,按end第一排序,按start第二排序*/
        qsort(a, n, sizeof(a[1]), cmp);
        int begin = a[0].end;
        for(i = 1; i < n; i++)
        {
            if(a[i].start>=begin)
            {
                c++;
                begin = a[i].end;
            }
        }
/*按end为排序依据,可以保证看完当前节目的时间最早进而保证看完的节目最多*/ 
        printf("%d\n", c);
    }
    return 0;
}

补充:
鉴于好久没有熟悉C语言把结构体相关知识忘差不多,所以自己补充一下关于结构体的知识:
struct 结构名
{
类型 变量名;
类型 变量名;

} 结构变量;
如果后面的程序里有调用,可以在struct前加typedef定义,typedef 只是为一种已经存在的类型定义一个新的名字而已,并未定义一种新的数据类型。
参考链接:
http://jingyan.baidu.com/article/af9f5a2d02525143140a45fa.html
关于qsort:
https://wenku.baidu.com/view/b65ccf0b03d8ce2f006623db.html

出租车费

时间限制: 1 Sec 内存限制: 32 MB

题目描述
某市出租车计价规则如下:起步4公里10元,即使你的行程没超过4公里;接下来的4公里,每公里2元;之后每公里2.4元。行程的最后一段即使不到1公里,也当作1公里计费。
一个乘客可以根据行程公里数合理安排坐车方式来使自己的打车费最小。
例如,整个行程为16公里,乘客应该将行程分成长度相同的两部分,每部分花费18元,总共花费36元。如果坐出租车一次走完全程要花费37.2元。
现在给你整个行程的公里数,请你计算坐出租车的最小花费。

输入
输入包含多组测试数据。每组输入一个正整数n(n<10000000),表示整个行程的公里数。
当n=0时,输入结束。
输出
对于每组输入,输出最小花费。如果需要的话,保留一位小数。
样例输入
3
9
16
0
样例输出
10
20.4
36
分析:
根据数学计算得出当路程为8时可获得最低的每公里车价,而在公里数为5时获得平均车价(2.4)所以将数据设出5和8两个节点,即凑出尽量多的8然后计算多出8的部分。

#include <stdio.h>

double fey(long n)
{
    double sum=0;
    int a, b;
    a = n/8;
    b = n%8;
    sum = a*18;
    if(b <=5)
    {
        if(a != 0)
        {
            sum += b*2.4;
        }
        else
        {
            if(b == 5)
            {
                sum += 12;
            }
            else sum +=10;
        }
    }
    else
    {
        sum += 10+(b-4)*2;
    }
    return sum;
}

int main(int argc,char* argv[])
{
    long n;
    while(scanf("%ld", &n)!=EOF&&n!=0)
    {
        if(0 == fey(n)-(int)(fey(n)+0.5))
        {
            printf("%.0lf\n", fey(n));
        }
        else
        {
            printf("%.1lf\n", fey(n));
        }
    }
    return 0;
}

木棒

时间限制: 1 Sec 内存限制: 32 MB
题目描述
现有n根木棒,已知它们的长度和重量。要用一部木工机一根一根地加工这些木棒。该机器在加工过程中需要一定的准备时间,是用于清洗机器,调整工具和模板的。木工机需要的准备时间如下:
(1)第一根木棒需要1min的准备时间;
(2)在加工了一根长为l,重为w的木棒之后,接着加工一根长为ll(l<=ll),重为ww(w<=ww)的木棒是不需要任何准备时间的。否则需要一分钟的准备时间。
给定n根木棒,你要找到最少的准备时间。例如现在有长和重分别为(4,9),(5,2),(2,1),(3,5)和(1,4)的五根木棒,那么所需准备时间最少为2min,顺序为(1,4),(3,5),(4,9),(2,1),(5,2)。
输入
输入包含多组测试数据。输入的第一行是一个整数T,表示测试数据的个数。
每个测试例两行:
第一行是一个整数n(1<=n<=5000),表示有多少根木棒;
第二行包括n*2个整数,表示了l1,w1,l2,w2,l3,w3,…,ln,wn,这些数均不大于10000,其中li和wi表示第i根木棒的长度和重量。
输出
输出以分钟为单位的最少准备时间。
样例输入
3
5
4 9 5 2 2 1 3 5 1 4
3
2 2 1 1 2 2
3
1 3 2 2 3 1
样例输出
2
1
3

#include <stdio.h>
#include <stdlib.h>

typedef struct stick
{
    int l,w;
    int v;
} sti;

int cmp(const void *x,const void *y)
{
    sti a = *((sti *)x);
    sti b = *((sti *)y);
    if(a.l==b.l)
        return a.w-b.w;
    return a.l-b.l;
}

int main()
{
    int i,t,k,n,cnt,ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        sti s[n];
        for(i=0; i<n; i++)
        {
            scanf("%d%d",&s[i].l,&s[i].w);
            s[i].v=0;
        }
        qsort(s,n,sizeof(s[0]),cmp);
        cnt=0;
        k=0;
        ans=0;
        while(cnt!=n)
        {
            k=0;
            while(k<n&&s[k].v==1)
                k++;
            ans++;
            for(i=k; i<n; i++)
            {
                if(s[i].v == 1)
                {
                    continue;
                }
                if(s[i].l>=s[k].l&&s[i].w>=s[k].w)
                {
                    s[i].v=1;
                    cnt++;
                    k=i;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

补充:
C_QSORT函数定义: void __cdecl qsort(void _Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void ,const void *));
返回值必须是int,两个参数的类型必须都是const void *

迷瘴

时间限制: 1 Sec 内存限制: 32 MB
题目描述
小明正在玩游戏,他控制的角色正面临着幽谷的考验——
幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死。
幸好小明早有防备,提前备好了解药材料(各种浓度的万能药水)。现在只需按照配置成不同比例的浓度。
现已知小明随身携带有n种浓度的万能药水,体积V都相同,浓度则分别为Pi%。并且知道,针对当时幽谷的瘴气情况,只需选择部分或者全部的万能药水,然后配置出浓度不大于 W%的药水即可解毒。
现在的问题是:如何配置此药,能得到最大体积的当前可用的解药呢?
特别说明:由于幽谷内设备的限制,只允许把一种已有的药全部混入另一种之中(即:不能出现对一种药只取它的一部分这样的操作)。
输入
输入数据的第一行是一个整数C,表示测试数据的组数;
每组测试数据包含2行,首先一行给出三个正整数n,V,W(1<=n,V,W<=100);
接着一行是n个整数,表示n种药水的浓度Pi%(1<=Pi<=100)。
输出
对于每组测试数据,请输出一个整数和一个浮点数;
其中整数表示解药的最大体积,浮点数表示解药的浓度(四舍五入保留2位小数);
如果不能配出满足要求的的解药,则请输出0 0.00。
样例输入
2
1 35 68
1
2 79 25
59 63
样例输出
35 0.01
0 0.00
解题:
由于液体体积一样,所以只需计算满足条件的最大浓度就好,在浓度满足条件内尽量加更多的解药

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int cmp ( const void *a , const void *b )
{
    return *(int *)a - *(int *)b;
}
int main(int argc,char* argv[])
{
    int c;
    scanf("%d", &c);
    while(c--)
    {
        int n, v, w, i;
        double pi;
        scanf("%d%d%d", &n, &v, &w);
        int p[n];
        for(i = 0; i < n; i++)
        {
            scanf("%d", &p[i]);
        }
        qsort(p, n, sizeof(p[0]), cmp);
        double sum =0;
        for(i = 0; i < n; i++)
        {
            sum += p[i];
            if(sum/(i+1) <= w)
            {
                pi = sum/(i+1);
            }
            else break;
        }
        if((i) == 0)
        {
            printf("0 0.00\n");
        }
        else
        {
            printf("%d %.2lf\n", (i)*v, pi/100);
        }

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值