Magic number

Description Title: Eastern see a magic number (greater than 0) on a set of ancient books, if all numbers a number of bits can be divided into several groups, wherein a set of numbers to another set of numbers equal to the sum of and, and that this number is the magic number. Now a given range, this range the number of seeking magic number!

数字224,可以分为(2,2)和(4)两组数字相等,符合神奇数的要求。

数字123可以分成(1,2)和(3)所以是神奇数。

234 无论那种分发都不能分成和相等的两组数,所以不是神奇数。

For this question, we need first to split this number in every store into an array, and these numbers are summed.

Digital limit we set is 9999999999! Then we need to set up an array of length 46 (not taken into account the type, because is not the point).

Why open an array of length 46? Below you reading this you will know.

The solution of the problem as I understand it is 将每组数字的加操作用数组的变化来表现出来.

First slowly through a simple example to understand that sentence I said above:

There is a whole element to false bool array a, there is an array tmp there a number of integer numbers. Now it requires all the elements of the integer array and, and the results obtained by querying the array a. How to solve?

Set sum = 0, the elements tmp is zero, sum plus tmp [0], set a [sum] = true, this element is sequentially changed to (a);

//这里为伪代码
int sum = 0;
//假设len为数组长度
for(int i=0;i<len;i++)
{
	sum += tmp[[i] ;	
	a[sum]=true ;
}
int index = 0 ;

Finally, only to find the last part can be a true where the subscript of, the subscript is an array tmp and all elements.
Here Insert Picture Description
Image above process is the process!

Here we look at the magic number to resolve the problem.

We assume that the maximum is determined to be the upper limit of the magic number 9999999999, of course, this number is a look at the magic number, each one separated, then divided into two groups of five 9, and both sides 45. For this number 9999999999, after the packet, wherein the sum of a group of words represented in the array of array bool:

Here Insert Picture Description

Value array [45] is 1, thereby determining the number is 9999999999 magic number.

So we use the same number of other ways to judge whether the segment is the magic number. This length of time to see how the array is set to 46, because the number is 9999999999, then for example
, a determination of the number of each divided into two groups, each sum, and determines whether or not 45. I.e., when the array [45] = 1, it follows that the number is the magic number.

After the above analysis, any number, any of his into two groups, one group as long as the determination of whether and sum / 2, that is, we are only concerned bool数组array[sum/2]是否为true即可(sum of the total number of each digit for the addition, and sum is an even number 这也是满足神奇数的前提条件, we initialize an array of bool are all false) , as long as the array [sum / 2] is true then it shows there is a subsequence tray is sum / 2, that is, the number is the magic number!

#include <iostream>
using namespace std ;

bool check(int num)
{
    int sum = 0 ;
    int a[20] ;
    int cur = 0 ;
    while(num>0)
    {
        a[cur] = num%10 ;
        sum += a[cur++] ;
        num=num/10 ;
    }

    if(sum%2 !=0)
    {
        return false ;
    }
    int t = sum/2 ;
    bool tmp[46] ={0};
    tmp[a[0]] = 1 ;

    for(int i=1; i<cur; i++)
    {
        int index = a[i] ;
        for(int j=45; j>=0; j--)
        {
            if(tmp[j] && j+index<46)
            {
                tmp[j+index] = 1 ;
            }
        }
        if(tmp[t] == 1)
        {
            return true ;
        }
    }
    return false ;
}

int main()
{
    int counts = 0 ;
    int m,n ;
    cin >> m >> n ;
    for(int i=m; i<n; i++)
    {
        if(check(i))
        {
            cout << i << endl ;
            counts ++ ;
        }
    }
    cout << counts << endl ;
    return 0;
}

Another method is to better understand recursion:


#include <iostream>
using namespace std;

bool isMagicArr(int index, int sum, int* nums) 
{
	if (sum == 0)		// 递归结束条件1
		return true;	
	if (sum < 0 || index < 0)		// 递归条件结束2, 累加和超过了或者数组中没有值了
		return false;
	// num[index]是sum中的一部分或者不是sum中的一部分
	return isMagicArr(index - 1, sum - nums[index], nums) || isMagicArr(index - 1, sum, nums);
}

bool checkMagic(int num)
{
	int nums[11];			// 把数字num按位存到nums中
	int index = 0;
	int sum = 0;			// 每位数字求和
	for ( ; num > 0; index++)
	{
		nums[index] = num % 10;		// 获取并保存每位数字 
		sum += nums[index];			// 每位数字累计求和
		num = num / 10;				// 除去个位数字
	}
	// 每位数和是奇数,则肯定不是神奇数
	if (sum % 2 != 0)
		return false;

	return isMagicArr(index, sum / 2, nums);
}

int main()
{
	int l = 0, r = 0;
		cin >> l >> r;
        int start = clock() ;
		int count = 0;
	    for (int num = l; num <= r; num++)
		{
			if (checkMagic(num)){
			    cout <<num <<endl ;
                count++;
		    }
        }
		cout << "神奇数总数:"<<count << endl;
        int end =clock() ;
        cout <<"总耗时:"<<end-start<<endl ;
        
    return 0;
}

The above two methods in the time cost is about the same!

Guess you like

Origin blog.csdn.net/qq_41681241/article/details/89342385