18118 勇者斗恶龙

/*Description
有n个头的恶龙,你希望雇一些骑士把它杀死(即砍掉所有头)。村里有m个骑士可以雇佣,一个能力值为x的骑士可以砍掉恶龙
一个直径不超过x的头,且需要支付x个金币。如何雇佣骑士才能砍掉恶龙的所有头,且需要支付的金币最少?注意,一个骑士只
能砍一个头(且不能被雇佣两次)

输入格式
多组数据,每组数据的第一行为正整数n和m(1 <= n, m <= 200000);以下n行每行为一个整数,即恶龙每个头的直径;以下m行每行为
一个整数,即每个骑士的能力。输入结束标志n=m=0;

输出格式:每组数据,输出最少花费,无解输出"Loowater is doomed!"

输入样例
2 3
5
4
7
8
4
2 1
5
5
10
0 0
输出样例
11
Loowater is doomed!
*/

虽然C语言在电脑编译器结果正确,输入输出循环细节处也参照AC的代码修改过,但仍无法通过OJ,显示超时

可能原因: AC的代码是通过C++实现的,使用了排序工具sort()函数,工具运用了最优的排序算法,效率较高,用时较短,而C语言的冒泡排序或者选择排序时间复杂度较大,所以显示超时,无法通过OJ

    sort函数用于C++中,对给定区间所有元素进行排序,默认为升序,也可进行降序排序。
    sort函数进行排序的时间复杂度为n*log2n,比冒泡之类的排序算法效率要高,
    sort函数包含在头文件为#include<algorithm>的c++标准库中。

-----------------------C语言实现,运用选择排序,冒泡排序

# include <stdio.h>
int main()
{
	int n = 0, m = 0;
	int i = 0, j = 0, sum = 0, temp = 0, flag, k;
	int diameter[200000], ability[200000];

	while (scanf("%d%d", &n, &m) != EOF, n || m) {
		//如果恶龙的头的个数大于0并且勇者个数为0
		if (n > 0 && m == 0) {
			printf("Loowater is doomed!\n");
			return 0;
		}

		for (i = 0; i < n; i++) {
			scanf("%d", &diameter[i]);
		}
		for (i = 0; i < m; i++) {
			scanf("%d", &ability[i]);
		}
		//对恶龙头的直径进行选择升序排序
		for (i = 0; i < n - 1; i++) {
			for (j = 1; j < n; j++) {
				if (diameter[i] > diameter[j]) {
					temp = diameter[i];
					diameter[i] = diameter[j];
					diameter[j] = temp;
				}
			}
		}

		//对勇者的能力进行冒泡升序排序
		for (i = 0; i < m; i++) {
			for (j = 0; j < m-1-i; j++) {
				if (ability[j] > ability[j + 1]) {
					temp = ability[j];
					ability[j] = ability[j + 1];
					ability[j + 1] = temp;
				}
			}
		}

		/*关键代码:计算最少的金币*/
		k = 0;
		sum = 0;
		for (i = 0; i < n; i++) {
            	flag = 1;                //假设每个恶龙的头的直径都能被勇者砍掉,做个标记
			for (j = k; j < m; j++) {
                if (diameter[i] <= ability[j]){ //如果直径小于等于勇者能力值
                    sum += ability[j];  //累加金币
                    k = j +1;           //因为前面对数据进行了排序,所以此处j+1就是遍历后面的勇者的能力值,确保不重复雇佣该勇者
                    flag = 0;           //改变标记,即该头不能被砍掉
                    break;              //结束内部循环,继续外部循环判断下一个头能不能被砍掉
                }

			}
			if (flag){                  //恶龙的这一个头不能被砍掉,输出无解并结束外部循环
                printf("Loowater is doomed!\n");
                return 0;
			}
		}
		/*如果恶龙的每一个头都被砍掉,则输出总金币并继续下一组测试实例*/
		if (i == n){
           	     printf("%d\n", sum);
		}

	}
}

AC sort()函数排序

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n, m, head[200000] = {0}, power[200000] = {0}, i, j;
    while (cin>>n>>m && !(n==0 && m==0))
    {
        long long sum = 0;
        for (i = 0; i < n; i++)
            scanf("%d", &head[i]);
        for (i = 0; i < m; i++)
            scanf("%d",&power[i]);
        if (n > m)
        {
            printf("Loowater is doomed!\n");
            continue;
        }
        sort(head,head+n);
        sort(power,power+m);
        j = 0;
        for (i = 0; i < n; i++)
        {
            for (;j < m; j++)
                if (head[i] <= power[j])
                {
                    sum+= power[j];
                    j++;
                    break;
                }
            if (j==m)
            {
                printf("Loowater is doomed!\n");
                break;
            }

        }
        if (i==n)
            printf("%lld\n",sum);
    }
    return 0;
}
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值