原本打算在新浪长微博上发,但是尼玛总提示敏感信息,我了个去,只好该在这里发了
ps:微博@骑猪猪吹泡泡
题目一主要思路:
把原问题转化成求两个小集合的子集和的问题,遍历原数组,为保持原数据不造破坏,正负数置于另外申请的空间,把负数转成正数存储,同时判断原数据是否有0元素的存在。将分开的正负数(现在变成两组正数集合假设为A,B)快排让其有序,同时进行优化,剔除不会参与求子集和的元素,也即,A中存在元素比B中所有元素的和都大,显然这样的元素无效,目的是尽可能减少元素个数以减少穷举子集和的次数。
然后选取元素个数少的集合来求子集和sum0,然后在另一集合中判断是否存在子集和等于sum0,同时在进入另一集合判断时仍就做优化处理,剔除集合中大于sum0的元素。总之就是尽量减少参与计算子集和的元素个数
代码如下
#include <iostream>
void quick_sort(int* input_array,int low,int high);
//判断input_array中元素是否存在子集和等于key,成功返回true
bool judge_subset(int* input_array,int length,unsigned int key);
//主操作,判断input_array中是否存在子集和为0,成功返回true
bool judge_sum_zero(int* input_array,int array_length)
{
if( 0==array_length || NULL==input_array)
return false;
int* sorted_array = new int[array_length];
unsigned int posi_sum=0,nega_sum=0;
unsigned int posi_count=0,nega_count=0;
int nega_begin_pos=0,nega_end_pos=-1;
int posi_begin_pos = array_length;
int posi_end_pos = array_length-1;
//将原数组中正负数分开存储
for(size_t i=0; i<array_length; ++i)
{
if( 0==input_array[i])
{
delete[] sorted_array;
return true;
}
else if(0<input_array[i])
{
sorted_array[--posi_begin_pos] = input_array[i];
++posi_count;
posi_sum += input_array[i];
}
else
{
sorted_array[++nega_end_pos] = -input_array[i];
++nega_count;
nega_sum += -input_array[i];
}
}
if( !(nega_count && posi_count)||(nega_sum == posi_sum) )
{
delete[] sorted_array;
return false;
}
quick_sort(sorted_array,nega_begin_pos,nega_end_pos);
quick_sort(sorted_array,posi_begin_pos,posi_end_pos);
for(size_t i=nega_end_pos; i<=nega_begin_pos; --i)
{
if(sorted_array[i] == posi_sum)
{
delete[] sorted_array;
return true;
}
else if(sorted_array[i] < posi_sum)
break;
else
{
--nega_end_pos;
--nega_count;
nega_sum -= sorted_array[i];
}
}
for(size_t i=posi_end_pos; i>=posi_begin_pos; --i)
{
if(sorted_array[i] == nega_sum)
{
delete[] sorted_array;
return true;
}
else if( sorted_array[i] <nega_sum)
break;
else
{
--posi_end_pos;
--posi_count;
posi_sum -= sorted_array[i];
}
}
/*litter_array_begin_pos 为数量少的集合元素起点
litter_array_end_pos 为数量少的集合元素终点
big_array_begin_pos 为数量多的集合元素起点
big_array_end_pos 为数量多的集合元素终点
递增排序
*/
int litter_array_begin_pos,litter_array_end_pos;
int big_array_begin_pos,big_array_end_pos;
unsigned int litter_array_sum;
unsigned int big_array_sum;
if(nega_count<=posi_count)
{
litter_array_begin_pos = nega_begin_pos;
litter_array_end_pos = nega_end_pos;
litter_array_sum = nega_sum;
big_array_begin_pos = posi_begin_pos;
big_array_end_pos = posi_end_pos;
big_array_sum = posi_sum;
}
else
{
litter_array_begin_pos = posi_begin_pos;
litter_array_end_pos = posi_end_pos;
litter_array_sum = posi_sum;
big_array_begin_pos = nega_begin_pos;
big_array_end_pos = nega_end_pos;
big_array_sum = nega_sum;
}
int litter_array_count = litter_array_end_pos
-litter_array_begin_pos+1;
int j;
unsigned int sum = big_array_sum;
int begin_pos=big_array_begin_pos,end_pos;
//开始计算数量少的集合的子集和
for(unsigned int i=1; i<(1<<litter_array_count); ++i)
{
litter_array_sum = 0;
end_pos = big_array_end_pos;
sum = big_array_sum;
for(j=0; j<litter_array_count; ++j)
{
if((i>>j)&0x01 ==0x01)
{
litter_array_sum += sorted_array[litter_array_begin_pos+j];
}
}
while(end_pos >=begin_pos)
{
if(litter_array_sum == sorted_array[end_pos])
{
delete[] sorted_array;
return true;
}
else if(litter_array_sum < sorted_array[end_pos])
{
sum -= sorted_array[end_pos];
--end_pos;
continue;
}
else
break;
}
if(litter_array_sum == sum)
{
delete[] sorted_array;
return true;
}
else if(litter_array_sum > sum)
continue;
if(end_pos<begin_pos)
continue;
if(judge_subset(&sorted_array[begin_pos]
,end_pos-begin_pos+1
,litter_array_sum))
{
delete[] sorted_array;
return true;
}
}
delete[] sorted_array;
return false;
}
void swap(int& a,int&b)
{
if(&a != &b)
{
a =a^b;
b =a^b;
a =a^b;
}
}
int partion(int* input_array,int low,int high)
{
int mid = low + (high-low)/2;
if(input_array[low]>input_array[high]&&low<high)
swap(input_array[low],input_array[high]);
if(input_array[mid]<input_array[low])
swap(input_array[mid],input_array[low]);
if(input_array[mid]>input_array[high])
swap(input_array[mid],input_array[high]);
int temp = input_array[low];
while(low<high)
{
while(input_array[high]>=temp && low<high)
--high;
input_array[low] = input_array[high];
while(input_array[low]<=temp && low<high)
++low;
input_array[high] = input_array[low];
}
input_array[low] = temp;
return low;
}
void quick_sort(int* input_array,int low,int high)
{
int pivot;
if(low<high)
{
pivot = partion(input_array,low,high);
quick_sort(input_array,low,pivot-1);
quick_sort(input_array,pivot+1,high);
}
}
bool judge_subset(int* input_array,int length,unsigned int key)
{
if(length<1)
return false;
unsigned int sum;
int j;
for(unsigned int i=1; i<(1<<(length)); ++i)
{
sum = 0;
for(j=0; j<length; ++j)
{
if( ((i>>j)&0x01) ==0x01)
sum += input_array[j];
if(sum == key)
return true;
else if(sum >key)
break;
}
}
return false;
}
using namespace std;
int main()
{
int a[]={-100,99,3,-5,300,-23,20,-102,45,9,-5,-5};
std::cout<<"result is:"<<judge_sum_zero(a,sizeof(a)/sizeof(int));
return 0;
}
题目二思路:
由于时间不多,没过多考虑就简单的这样处理,为结点添加4个域:
一个数据域,一个队列结构的next指针,一个用于有序结构指向前结点的sorted_prior指针,一个指向有序表的sorted_next指针,
所以,队列维护两个链表,一个用于满足队列结构的表,一个用于维护元素有序结构的表,添加双向的原因,主要考虑在删除结点时方便。
#include "stdafx.h"
#include <iostream>
template<class type>
class queue_node
{
public:
queue_node(type value)
{
data = value;
next = NULL;
sorted_prior = NULL;
sorted_next =NULL;
}
~queue_node()
{
}
type data;
queue_node* next;
queue_node* sorted_prior;
queue_node* sorted_next;
};
template<class type>
class queue
{
public:
queue()
{
head = NULL;
tail = NULL;
sorted_list = NULL;
length = 0;
}
~queue()
{
if( 0 ==length)
return;
queue_node<type> *p = head;
queue_node<type> *q = p->next;
while(p)
{
delete p;
p = q->next;
}
}
//添加新结点
void push_back(type data);
//移除队头元素
void pop();
//获取队头元素,成功返回true,同时value的值为队头元素值
bool get_head(type& value) const;
//获取队列最大元素
bool get_max_value(type& value) const;
//获取队列长度
inline size_t get_length() const;
private:
inline void rm_sorted_node(queue_node<type>* rm_node);
inline void add_sorted_node(queue_node<type>* add_node);
private:
queue_node<type>* head;
queue_node<type>* tail;
queue_node<type>* sorted_list;
size_t length;
};
template <class type> void
queue<type>::push_back(type data)
{
queue_node<type> *node = new queue_node<type>(data);
if (!length)
head =tail = node;
else
{
tail->next = node;
tail = tail->next;
}
++length;
add_sorted_node(node);
}
template <class type> void
queue<type>::pop()
{
queue_node<type> *node = head;
if (node)
{ rm_sorted_node(node);
head = head->next;
delete node;
--length;
}
if( !length)
head = tail = NULL;
}
template <class type> inline size_t
queue<type>::get_length() const
{
return this->length;
}
template <class type> bool
queue<type>::get_head(type& value) const
{
if(!get_length())
return false;
value = head->data;
return true;
}
template <class type> bool
queue<type>::get_max_value(type& value) const
{
if(sorted_list)
value = sorted_list->data;
else
return false;
return true;
}
template <class type> inline void
queue<type>::rm_sorted_node(queue_node<type>* rm_node)
{
if(!rm_node->sorted_prior)
{
sorted_list = rm_node->sorted_next;
if(sorted_list)
{
sorted_list->sorted_prior = NULL;
}
return;
}
rm_node->sorted_prior->sorted_next = rm_node->sorted_next;
if(rm_node->sorted_next)
rm_node->sorted_next->sorted_prior = rm_node->sorted_prior;
}
template <class type> inline void
queue<type>::add_sorted_node(queue_node<type>* add_node)
{
if(!sorted_list)
{
sorted_list = add_node;
return;
}
queue_node<type>* temp_node;
temp_node = sorted_list;
while(temp_node->sorted_next &&(temp_node->data > add_node->data))
temp_node = temp_node->sorted_next;
if(!temp_node->sorted_next &&(temp_node->data > add_node->data))
{
add_node->sorted_prior = temp_node;
temp_node->sorted_next = add_node;
}
else
{
add_node->sorted_next = temp_node;
add_node->sorted_prior = temp_node->sorted_prior;
if(temp_node->sorted_prior)
temp_node->sorted_prior->sorted_next = add_node;
else
sorted_list = add_node;
temp_node->sorted_prior = add_node;
}
}
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
queue<int> my_queue;
int a[] = {213,435,32,34,54,65,2,776,32,65,21,43,23,55,76,23,76,88,43,12};
for(int i=0;i<(sizeof(a)/sizeof(int));++i)
my_queue.push_back(a[i]);
int max = 0;
my_queue.get_max_value(max);
cout<<"最大值为:"<<max<<endl;
for(int i=0;i<(sizeof(a)/sizeof(int)); ++i)
{
int value =0;
my_queue.get_head(value);
std::cout<<"移除元素"<<value<<endl;
my_queue.pop();
my_queue.get_max_value(max);
cout<<"此时队列最大值为:"<<max<<endl;
}
return 0;
}