1. 程式人生 > >【演算法題】神奇數

【演算法題】神奇數

東東在一本古籍上看到有一種神奇數,如果能夠將一個數的數字分成兩組,其中一組數字的和等於另外一組數字的和,我們就將這個數稱為神奇數。例如242就是神奇數,我們能夠將這個數字分成兩組,分別是{2,2}以及{4},給定區間[l,r],統計這個區間有多少個神奇數,請你來幫助他。

這裡寫圖片描述

首先判斷陣列能否被平分,即陣列分割問題,

dp[i][j]表示陣列前 i 個數字能否求和得到 j

dp[i][j]=dp[i1][j]||dp[i1][jarray[i]]

其中||是邏輯或運算。

優化:

1、若sum(array)為奇數,直接返回false
2、使用逆序迴圈將dp陣列簡化為一維陣列

[l,r]區間很大,可以使用map儲存已經計算過神奇數的數,之後如果有元素一致的數,可以直接查詢結果。

如計算到”12345”為非神奇數,則之後遍歷到”21345”、”23145”、”23415”、”23451”、“31245”、、、、都是非神奇數

#include <iostream>
#include <math.h>
#include <vector>
#include <algorithm>
#include <numeric>
#include <map>

using namespace::std
; //#define debug_ int lef = 0, righ = 0; bool IsMagical(vector<char>& vec) { int len = vec.size(); int sum = accumulate(vec.begin(), vec.end(), 0); if (sum & 1) return false; int mid = (sum>>1); vector<int> dp(mid + 1, 0); dp[0] = 1; for (int
i = 0; i < len; ++i) { for (int j = mid; j > 0; --j) { if (j >= vec[i]) dp[j] = max(dp[j], dp[j - vec[i]]); } } if (dp[mid]) return true; else return false; } vector<char> getsortnum(int i) { vector<char> vec; vec.reserve(10); int tmp; while (i) { tmp = i % 10; i = i / 10; vec.push_back(tmp); } sort(vec.begin(), vec.end()); return vec; } void func(int lef, int righ) { int count(0); bool flag; map<vector<char>, bool> my_map; for (auto i = lef; i <= righ; ++i) { vector<char> sorted_num; sorted_num.reserve(10); char tmp(0); int i_tmp(i); while (i_tmp) { tmp = i_tmp % 10; i_tmp = i_tmp / 10; sorted_num.push_back(tmp); } sort(sorted_num.begin(), sorted_num.end()); auto iter = my_map.find(sorted_num); if (iter == my_map.end()) { flag = IsMagical(sorted_num); my_map[sorted_num] = flag; if (flag) ++count; } else { if (iter->second) ++count; } } cout<< count<<endl; } int main() { #ifdef debug_ lef = 1; righ = 50; #else cin >> lef; cin >> righ; #endif func(lef, righ); return 0; }

相關推薦

演算法奇數

東東在一本古籍上看到有一種神奇數,如果能夠將一個數的數字分成兩組,其中一組數字的和等於另外一組數字的和,我們就將這個數稱為神奇數。例如242就是神奇數,我們能夠將這個數字分成兩組,分別是{2,2}以及{4},給定區間[l,r],統計這個區間有多少個神奇數,請你來

演算法加一

/* 給定一個由整陣列成的非空陣列所表示的非負整數,在該數的基礎上加一。 最高位數字存放在陣列的首位, 陣列中每個元素只儲存一個數字。 你可以假設除了整數 0 之外,這個整數不會以零開頭。 示例 1: 輸入: [1,2,3] 輸出: [1,2,4] 解釋: 輸入陣列表示數字 123。 示例

演算法要求對陣列中的元素進行重新排列,負數放到前面,不改變相對順序

import java.util.Scanner; /**  *  題目描述 給定一個未排序的整數陣列,陣列中的元素有正數也有負數,要求對陣列中的元素進行重新排列, 使得負數排在正數的前面,並且不改變原來正數和負數之間的相對順序。例如,如果輸入是{1,7,-5,9,-12,

演算法網易程式設計:暗黑字串組合數

題目 一個字串僅由’A’,’B’,’C’三個字元組成,若字串中不存在’A’,’B’,’C’三個字元相鄰的子串(比如ABC,BAC等),則該字串稱為暗黑字串,否則稱為單純字串。 求長度為L的此種字串中有多少種是暗黑字串? 例子: 字串 AABBA

演算法雙向氣泡排序

void func(int* array,int len) { if (array == NULL || len<=1) { return; } int left = -1; int right =

演算法查詢字串中無重複最長子串的長度

在閱讀的過程中有任何問題,歡迎一起交流 QQ:1494713801 題目:輸入是一個字串,找出沒有重複字元的最長子字串的長度 示例: “abcabcbb”最長子串(abc)長度為3   “bbbbbbb”最長子串(b)長度為1 “abdevbac”最長子串(bdev)

演算法最大深度,最小深度

最大深度 求一顆二叉樹的最大深度 深度優先搜尋、遞迴 int MaxDepth(TreeNode * root) { if (root ==NULL) { return 0; } return max

演算法買蘋果

小易去附近的商店買蘋果,奸詐的商販使用了捆綁交易,只提供6個每袋和8個每袋的包裝(包裝不可拆分)。 可是小易現在只想購買恰好n個蘋果,小易想購買儘量少的袋數方便攜帶。如果不能購買恰好n個蘋果,小易將不會購買。 輸入描述: 輸入一個整數n,

演算法01揹包問題

寫於2017/11/17 1、問題描述 有m件物品,它們的重量分別是W1,W2,…,Wm,它們的價值分別是V1,V2,…,Vm,現在給你個承重為n的揹包,如何讓揹包裡裝入的物品具有最大的價值總和? 2、解題思路 典型的動態規劃問題。 為

演算法最大的奇約數

小易是一個數論愛好者,並且對於一個數的奇數約數十分感興趣。一天小易遇到這樣一個問題: 定義函式f(x)為x最大的奇數約數,x為正整數。 例如:f(44) = 11. 現在給出一個N,需要求出 f(1) + f(2) + f(3)…….f(N)

演算法使用遞迴和非遞迴實現單向連結串列的轉置

在閱讀的過程中有任何問題,歡迎一起交流 QQ:1494713801 問題: 給一個單向連結串列,把它從頭到尾反轉過來。比如: a -> b -> c ->d 反過來就是 d -> c -> b -> a 。 分析: 假設每一個node

演算法找整除

牛牛想在[a, b]區間內找到一些數滿足可以被一個整數c整除,現在你需要幫助牛牛統計區間內一共有多少個這樣的數滿足條件? 輸入描述: 首先輸入兩個整數a,b,(-5*10^8 ≤ a ≤ b ≤ 5*10^8) 接著是一個正整數c(1 <=

演算法找到陣列中和為固定值的兩個元素

在閱讀的過程中有任何問題,歡迎一起交流 QQ:1494713801 題目:編寫一個函式,輸入為一個int型的陣列numbers和一個int型變數target,找到這個陣列中和為target的兩個元素,輸出其index。 假設每組輸入有且僅有一組輸出 示例: Input

BZOJ 3926 [Zjoi2015]諸眷顧的幻想鄉

發現 正整數 出現 code n-1 h+ 輸出 太陽 ++ Description 幽香是全幻想鄉裏最受人歡迎的萌妹子,這天,是幽香的2600歲生日,無數幽香的粉絲到了幽香家門前的太陽花田上來為幽香慶祝生日。 粉絲們非常熱情,自發組織表演了一系列節目給幽香看。幽香當然也非

從尾到頭列印連結串列——一天一道演算法

輸入一個連結串列,按連結串列值從尾到頭的順序返回一個ArrayList。 思想:棧的思想 # -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x #

筆試題中的演算法

1.【愛奇藝】N個盒子,第i個盒子是邊長為a[i]的立方體,如果一個盒子嚴格小於另一個盒子,並且大盒子裡沒有其他小盒子,小盒子沒放入大盒子中,那麼這個小盒子可以放入大盒子裡。可以根據條件任意放盒子,求最後能看見的最少盒子數量。(應該是求重複值最大的個數)先排序後求值 a =

leetcode:Minimum Depth of Binary Tree(樹的根節點到葉子節點的最小距離)面試演算法

題目: Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shortest path from the root node d

leetcode:N-Queens (n皇后問題) 面試演算法

題目:The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other. Given an

leetcode:Remove Duplicates from Sorted Array II (允許重複一次,去掉陣列多餘數字)面試演算法

題目: Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For example, Given sorted array A = [1,1,1,2,2,3]

leetcode:Plus One (加一)面試演算法

題目:Given a number represented as an array of digits, plus one to the number. 題意動態陣列存了一些個位數字,組成一個大數,計算這個大數加一之後的值。 模擬大數的加法,當沒有進位的時候就可以彈出迴圈