SRM 622 DIV 2

A.250

水题,求一个数字到距离他最近的斐波那契数的距离。

Problem Statement

 The Fibonacci sequence is defined as follows:
  • F[0] = 0
  • F[1] = 1
  • for each i >= 2: F[i] = F[i-1] + F[i-2]
Thus, the Fibonacci sequence starts as follows: 0, 1, 1, 2, 3, 5, 8, 13, ... The elements of the Fibonacci sequence are called Fibonacci numbers.

You're given an int N. You want to change N into a Fibonacci number. This change will consist of zero or more steps. In each step, you can either increment or decrement the number you currently have. That is, in each step you can change your current number X either to X+1 or to X-1.

Return the smallest number of steps needed to change N into a Fibonacci number.

Definition

 
Class:FibonacciDiv2
Method:find
Parameters:int
Returns:int
Method signature:int find(int N)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):256

Constraints

-N will be between 1 and 1,000,000, inclusive.

Examples

0) 
 
1
Returns: 0
The number 1 is already a Fibonacci number. No changes are necessary.
1) 
 
13
Returns: 0
The number 13 is also a Fibonacci number.
2) 
 
15
Returns: 2
The best way to change 15 into a Fibonacci number is to decrement it twice in a row (15 -> 14 -> 13).
3) 
 
19
Returns: 2
You can increase it by 2 to get 21.
4) 
 
1000000
Returns: 167960
This is the biggest possible number that you can get as input.

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 1000100
///#define LL __int64
#define LL long long
#define INF 0x3fffffff
#define PI 3.1415926535898

using namespace std;

const int maxn = 510;

class FibonacciDiv2
{
public:
    int find(int N)
    {
        LL num[45];
        int s = 0;
        num[0] = 0;
        num[1] = 1;
        for(int i = 2; i <= 40; i++)
            num[i] = num[i-1]+num[i-2];

        for(int i = 0; i <= 40; i++)
        {
            if(num[i] >= N)
            {
                s = i;
                break;
            }
        }
        int Max;
        int t = INF;
        int tt = INF;
        t = num[s]-N;
        if(s > 0)
            tt = N-num[s-1];
        Max = min(t, tt);
        return Max;
    }
};
B.500

给你n个数字,让你用体积为2^i的盒子把每一个装起来,并且体积相同的盒子可以换一个大盒子。求出最后的盒子最小为多大。我是当做2048来做的,枚举前两个,然后去掉前两个把新的体积加进来,然后sort再枚举前两个。。。

Problem Statement

 Today is Fox Ciel's birthday. You want to give her a box of candies as a present.

You have candies of several different types. You are given a int[] candyCounts. Each element ofcandyCounts is the number of candies of one particular type.

For each non-negative integer i, you have an unlimited supply of boxes with volume 2^i. That is, you have boxes with volume 1, 2, 4, 8, and so on.

You are going to pack the candies into boxes. Each type of candies has to be packed into a single box, and you have to use different boxes for different types of candy. The volume of a box must be greater than or equal to the number of candies it contains.

Once you have each type of candies in a box, you want to pack those boxes into larger boxes, until only one box remains. You can only pack two boxes at a time. That is, you can take any two boxes you currently have, get a new box, and put the two old boxes into the new box. This is possible if and only if the volume of the new box is greater than or equal to the sum of volumes of the two old boxes. You always get to choose which two boxes you want to pack together, and how large the new box should be.

To summarize:
  • First, you will pack all the candies into boxes.
  • Then, you will pack all those boxes into larger boxes, until you are left with a single box that contains everything.

Compute and return the smallest possible volume of the box obtained at the end of packing.

Definition

 
Class:BoxesDiv2
Method:findSize
Parameters:int[]
Returns:int
Method signature:int findSize(int[] candyCounts)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):256

Notes

-You may assume that the return value always fits into a signed 32-bit integer variable.

Constraints

-candyCounts will contain between 1 and 100 elements, inclusive.
-Each element of candyCounts will be between 1 and 1000, inclusive.

Examples

0) 
 
{8,8}
Returns: 16
First, you pack each type of candies into a box with volume 8. Then, you pack the two boxes into a single box with volume 16.
1) 
 
{5,6}
Returns: 16
Even though you have fewer candies than in Example 0, you still have to use boxes with volume 8 (or more) to store them.
2) 
 
{1,7}
Returns: 16
Now you could pack the 1 candy into a smaller box, but it will not help: you still have to use a box with volume 16 to store the two boxes with candies.
3) 
 
{1,1,13,1,1}
Returns: 32
4) 
 
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}
Returns: 1024

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 1000100
///#define LL __int64
#define LL long long
#define INF 0x3fffffff
#define PI 3.1415926535898

using namespace std;

const int maxn = 510;

class Subsets
{
    vector<int> num
public:
    int findSubset(vector <int> numbers)
    {
        int num[1010];
        int f[1010];
        int n = candyCounts.size();
        for(int i = 0; i < n; i++)
            num[i] = candyCounts[i];
        for(int i = 0; i < n ; i++)
        {
            for(int j = 0; j <= 10; j++)
            {
                if((1<<j) >= num[i])
                {
                    f[i] = (1<<j);
                    break;
                }
            }
        }
        while(1)
        {
            sort(f, f+n);
            if(n == 1)
            {
                break;
            }
            int s = (max(f[0], f[1]))*2;
            num[0] = s;
            for(int i = 2; i < n; i++)
                num[i-1] = f[i];
            n--;
            for(int i = 0; i < n; i++)
                    f[i] = num[i];
        }
        return f[0];
    }
};

C.1000

给你n个数字,让你求出这里面有多少种组合可以使得,这几个数的和大于他们的乘积。

先sort排序然后dfs一遍,注意相同的数字的处理。

Problem Statement

 You have a bag with some balls. There is a positive integer written on each of the balls. Balls with the same integer are identical.

A bag with balls is nice if the sum of numbers on all balls is strictly greater than the product of those numbers. For example, if the numbers on balls are {1,1,2,3}, the bag is nice because 1+1+2+3 > 1*1*2*3.

You are given a vector <int> numbers. Each element of numbers is a number written on one of the balls in your bag. You are going to remove some (possibly none, but not all) balls from the bag. After you do so, the bag must be nice.

Return the number of different nice bags you can obtain.

Definition

 
Class:Subsets
Method:findSubset
Parameters:vector <int>
Returns:int
Method signature:int findSubset(vector <int> numbers)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):256

Notes

-You may assume that the return value always fits into a signed 32-bit integer variable.

Constraints

-numbers will contain between 1 and 1000 elements, inclusive.
-Each element of numbers will be between 1 and 1000, inclusive.

Examples

0) 
 
{1,1,1}
Returns: 2
The bag contains three identical balls, each with the number 1.
We can produce a nice bag in two ways:
  • Keep all three balls. The bag is nice because 1+1+1 > 1*1*1.
  • Throw away one ball. The bag is nice because 1+1 > 1*1.
1) 
 
{1,1,1,1,2,2,2,2}
Returns: 13
Our bag contains 8 balls: four with a 1 and four with a 2.
All possible nice bags that can be produced by removing some of these balls are listed below, one per row.

1,1
1,1,1
1,1,1,1
1,2
1,1,2
1,1,1,2
1,1,1,1,2
1,2,2
1,1,2,2
1,1,1,2,2
1,1,1,1,2,2
1,1,1,2,2,2
1,1,1,1,2,2,2
2) 
 
{1,2,3,4}
Returns: 3
3) 
 
{1,1,1,1,1,1,1,1,1,1,1,1,1,10,20,30,40,50}
Returns: 77
4) 
 
{1,1,1,1,1,1,1,1,1,1,1,2,3,4,2,2,2}
Returns: 100
5) 
 
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,2,2,2,3,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22}
Returns: 8050
6) 
 
{5,3}
Returns: 0

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 1000100
///#define LL __int64
#define LL long long
#define INF 0x3fffffff
#define PI 3.1415926535898


using namespace std;


const int maxn = 510;


class Subsets
{
    vector<int> num;
    int n;
    int ans;
    void dfs(int x, int sum, int pro)
    {
        if(x == n)
            return;
        for(int i = x; i < n; i++)
        {
            if((x == i || num[i] != num[i-1]) && sum+num[i] > pro*num[i])
            {
                ans ++;
                dfs(i+1, sum+num[i], pro*num[i]);
            }
        }
    }
public:
    int findSubset(vector <int> numbers)
    {
        num = numbers;
        n = num.size();
        ans = 0;
        sort(num.begin(), num.end());
        dfs(1, num[0], num[0]);
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值