zoukankan      html  css  js  c++  java
  • 贪心算法

    认真读题

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

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

    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
    ", 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
    ", i+1);  
        }  
      
        return 0;  
    }  
  • 相关阅读:
    常见时间复杂度及对应关系
    【转载】Locust实现集合点
    curl 查看接口的网络分段响应时间
    python-字符串操作分类小结
    Jquery--1--选择器分类
    【转】linux shell编程实例总结
    随笔分类整理
    linux备忘录-日志档案
    linux备忘录-系统服务daemon
    linux备忘录-程序管理与SELinux
  • 原文地址:https://www.cnblogs.com/virusdefender/p/3415642.html
Copyright © 2011-2022 走看看