贪心算法

认真读题

貌似贪心算法中很多要进行排序的

----------------------------------------------------------------------------

http://acm.nyist.net/JudgeOnline/problem.php?pid=71

先把各个人的体重排序,然后计算最重的人和最轻的人能否同乘一条舟,如果不能,则最重的人就要单独乘坐一条舟,再求最轻的和第二重的人的和,依次比较。

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

int cmp_1(const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
}

int main()
{
    int n;
    int max_weight;
    int people_num;
    int people_weight[300];
    int i;
    int rear;
    int boat_num;
    scanf("%d", &n);
    while (n--)
    {
        boat_num = 0;
        memset(people_weight, 0, sizeof(people_weight));
        scanf("%d%d", &max_weight, &people_num);
        rear = people_num - 1;
        for (i = 0; i < people_num; i++)
        {
            scanf("%d", &people_weight[i]);
        }
        //对人的重量进行排序
        qsort(people_weight, people_num, sizeof(people_weight[0]), cmp_1);
        for (i = 0; i <= rear;)
        {
            if (i != rear)
            {

                if (people_weight[i] + people_weight[rear] <= max_weight)
                {
                    boat_num++;
                    rear--;
                    i++;
                }
                else
                {
                    if (people_weight[i] >= people_weight[rear])
                    {
                        boat_num++;
                        i++;
                    }
                    else
                    {
                        rear--;
                        boat_num++;
                    }
                    
                }
            }
            else
            {
                boat_num++;
                break;
            }
        }
        printf("%d\n", boat_num);
    }


    return 0;
}

 

---------------------------------------------------------------------

http://acm.nyist.net/JudgeOnline/problem.php?pid=448

/*
首先是在source_num的前source_num_len - del_num_len + 1中取最大的数字
因为至少要剩下source_num_len - del_num_len位数字来补齐其余的数字
比如1 0 5 7 8 9   长度为7  要删除的数字个数是3  所以必须在前4位中找数字
即使最大的数字是第4个,还有剩下的数字能用来补全的
然后继续这样的循环
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

int main()
{
    int ncase;
    char s[110], ans[110];
    int m, len, sign, max, num;
    scanf("%d", &ncase);
    while(ncase--)
    {
        num = sign = 0;
        scanf("%s%d", s, &m);
        len = strlen(s);
        for(int i = 0; i < len - m; ++i) //找m次最大值
        {
            max = -1;
            for(int j = sign; j <= m + i; ++j) //j的范围不能错~保证位数
            {
                if(max < s[j] - '0')
                {
                    max = s[j] - '0';
                    sign = j;
                }
            }
            ans[num++] = s[sign++];
        }
        for(int i = 0; i < len - m; ++i)
            cout<<ans[i] - '0';
        cout<<endl;
    }
    return 0;
}        

 

------------------------------------------------------------------------------------------------------

http://acm.nyist.net/JudgeOnline/problem.php?pid=6

自己画图看看就行

 

算出 这个草地的斜边长度, 然后只要全部圆的半径合大于等于这个斜边长度的一半就可以了(但是必须丢弃半径小于等于1的装置,在横中线上无论怎么放,它是无法完全覆盖草地的)。

#include <cstdio>  
#include <cstdlib>  
#include <cmath>  
  
int compare (const void * a, const void * b)  
{  
    return *(double *)b > *(double *)a ? 1 : -1;  
}  
  
     
int main( int argc, char **argv )  
{  
    int n;  
    scanf("%d", &n);  
    double buf[600];  
    // 草地斜边长度的一半  
    double len = sqrt(20*20 + 2*2)/2;  
  
    while ( n-- )  
    {  
        int m;  
        scanf("%d", &m);  
        for ( int i = 0; i < m; ++i )  
            scanf("%lf", buf+i);   
  
       // 从大到小排  
       qsort (buf, m, sizeof(buf[0]), compare);  
       double sum = 0;  
       int i;  
       for ( i = 0; i < m; ++i )  
       {  
           if (buf[i] <= 1)
                break;
           sum += buf[i];  
           if ( sum >= len ) // 半径和大于等于草地斜边长度一半就满足条件了  
               break;  
       }  
  
       printf( "%d\n", i+1);  
    }  
  
    return 0;  
}  

 

posted @ 2013-11-09 15:00  virusdefender  阅读(192)  评论(0编辑  收藏  举报