SGU 410 Galaxy in danger --贪心,想法题

题意:有n个星球,每个星球有Ai个人,每次有两种选择,第一是从每个星球上去掉1个人,第二个选择是选择一个星球放置一个科学家,将该星球的人数加倍,问最少多少次能够将所有星球上的人数同时变为0,并且如果步数<=1000,还要输出操作顺序。

解法:找出人数最多的那个星球,设最大人数为maxi,那么跑一个循环,每次该星球如果人数<maxi,那么能加倍就加倍到离maxi最近的位置,然后计算他们的差,比如2 1035,加倍后为1024 1035,差为11,那么到时候1024减到11的时候,1035变成了22,那么这个时候马上加倍11,再减即可。每个不等于最大人数的星球上都这样处理即可。predouble[]记录处理前先要加倍到离最大数最近的位置的星球,backdouble[]记录减到差值的时候要加倍的星球。然后输出即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 100007

int a[N];
int backdouble[5003][2];
int predouble[5004];

int main()
{
    int n,i,j,maxi = 0,kb,kp,ans = 0,flag = 1;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i] == 0)
            flag = 0;
        maxi = max(maxi,a[i]);
    }
    if(!flag)
    {
        puts("0");
        return 0;
    }
    kb = kp = 0;
    for(i=1;i<=n;i++)
    {
        if(a[i] == maxi)
            continue;
        int tmp = a[i];
        while(tmp < maxi)
        {
            if(maxi+ans <= 1000)  //还能输出
            {
                if(2*tmp<=maxi && kp <= 1000)
                    predouble[kp++] = i;
                else
                {
                    backdouble[kb][0] = i;
                    backdouble[kb++][1] = 2*(maxi-tmp);
                }
            }
            tmp *= 2;
            ans++;
        }
    }
    printf("%d\n",maxi+ans);
    if(ans+maxi > 1000)
        return 0;
    for(i=0;i<kp;i++)
        printf("science mission to the planet %d\n",predouble[i]);
    for(i=maxi;i>0;i--)
    {
        for(j=0;j<kb;j++)
            if(backdouble[j][1] == i)
                printf("science mission to the planet %d\n",backdouble[j][0]);
        puts("flying mission");
    }
    return 0;
}

SGU 410 Galaxy in danger --贪心,想法题

时间: 2024-10-24 14:54:11

SGU 410 Galaxy in danger --贪心,想法题的相关文章

POJ 2965 The Pilots Brothers&#39; refrigerator (想法题)

POJ 2965 题意: 输入一个形如: -+-- ---- ---- -+-- 4*4图案,+表示close,-表示open,定义一种操作为:改变某个单元格符号(+变-,-变+),同时单元格所在行与所在列的所有单元格符号都会发生改变. 求最少操作次数能使所有单元格内都是'-'.并输出要操作的单元格. 思路: 正常的做法和POJ 1573类似,dfs枚举即可,见code1. 这里提供一种高效的做法: 通过思考我们可以验证,某一个单元格内符号为'+',同时对其所在行与所在列的所有单元格进行操作(其

HDU 2410 Barbara Bennett&#39;s Wild Numbers (想法题)

题目链接:HDU 2410 Barbara Bennett's Wild Numbers 题意:给出两串数w,s(长度相同),第一串中有"?",问"?"取的值使w对应的数大于s对应的数 的最大方案数. 思路:W,S一一对应比较: 遇到第一个'?'之前比较情况 1.w[i]<s[i] 方案数0种:break: 2.w[i]>s[i] break.之后有n个''?' 方案数就有10的n次方种. 3.w[i]=s[i] 继续比较,重复1.2两个条件. 遇到'?

贪心/思维题 Codeforces Round #310 (Div. 2) C. Case of Matryoshkas

题目传送门 1 /* 2 题意:套娃娃,可以套一个单独的娃娃,或者把最后面的娃娃取出,最后使得0-1-2-...-(n-1),问最少要几步 3 贪心/思维题:娃娃的状态:取出+套上(2),套上(1), 已套上(0),先从1开始找到已经套好的娃娃层数, 4 其他是2次操作,还要减去k-1个娃娃是只要套上就可以 5 详细解释:http://blog.csdn.net/firstlucker/article/details/46671251 6 */ 7 #include <cstdio> 8 #i

1093. Count PAT&#39;s (25)想法题吧,算是排列组合吧

1093. Count PAT's (25) 时间限制 120 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CAO, Peng The string APPAPT contains two PAT's as substrings. The first one is formed by the 2nd, the 4th, and the 6th characters, and the second one is formed by the 3r

HDU 2410 Barbara Bennett&amp;#39;s Wild Numbers (想法题)

题目链接:HDU 2410 Barbara Bennett's Wild Numbers 题意:给出两串数w,s(长度同样),第一串中有"?",问"?"取的值使w相应的数大于s相应的数 的最慷慨案数. 思路:W,S一一相应比較: 遇到第一个'?'之前比較情况 1.w[i]<s[i] 方案数0种:break: 2.w[i]>s[i] break. 之后有n个''?' 方案数就有10的n次方种. 3.w[i]=s[i] 继续比較.反复1.2两个条件. 遇到'

HDU 4972 Bisharp and Charizard 想法题

Bisharp and Charizard Time Limit: 1 Sec  Memory Limit: 256 MB Description Dragon is watching NBA. He loves James and Miami Heat. Here's an introduction of basketball game:http://en.wikipedia.org/wiki/Basketball. However the game in Dragon's version i

HDU - 5806 NanoApe Loves Sequence Ⅱ 想法题

http://acm.hdu.edu.cn/showproblem.php?pid=5806 题意:给你一个n元素序列,求第k大的数大于等于m的子序列的个数. 题解:题目要求很奇怪,很多头绪但写不出,选择跳过的题,简称想法题. 首先考虑区间的更新方法:区间左端l不动,右端r滑动, 滑到有k个数>=m时,此区间符合条件,并且发现右端点再往右滑到底,此条件一直符合(因为若加入的数小于"第K大的数",则毫无影响.若不然,加入该数会产生一个新的第k大数,保证>="第K大

【CF700B】Connecting Universities(想法题,贪心,树上最短路)

题意:给出一棵树上的2*k个节点,给他们配对,使得他们之间的距离和最大. 思路:一条边的两侧如果有一侧没有给定的节点就不会被经过…… 如果有1个节点就会被经过1次…… 如果两侧分别有x,y个给定节点就会被经过min(x,y)次 因为要使总路程最大就是让每一条路被走过最多的次数 肯定是两侧各取一个 剩下的只能在某侧内部解决 所以按此统计即可 答案很大 用INT64 1 var head,vet,next,a,b,c,dep,flag,f:array[1..500000]of longint; 2

hdu 4550 贪心 思维题 不错

http://acm.hdu.edu.cn/showproblem.php?pid=4550 想了挺久,然后各种分类 终于AC,如果是现场,对自己没信心的话,估计还是要WA,,,,,,然后搜题解,发现人家都认为是简单题,看来我还是太弱了,牡丹江没有做出来K看来还是自己贪心和思维有问题 d是一个Deque 最朴素的算法是,如果当前的数<=d.front(),那么插入队列的前面,否则插入队列后面,但是有零所以需要单独处理,还是自己多举例找规律 我的策略: 1.记录0的个数zero,最小非零的数的个数