找回密码
 欢迎注册
楼主: mathe

[擂台] 最小无法表达的正整数

[复制链接]
发表于 2008-10-3 10:34:53 | 显示全部楼层
你什么时候想明白,不用考虑括号了
你才能参与这个题目的

这个题目根本不用考虑括号的问题!!
当然,不是不用括号

PS:
我的那个估计是很不准确的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-10-3 12:35:12 | 显示全部楼层
我不知道你怎么搜索的(没有看你的代码),但是我简单修改了一下我以前的代码,直接试着搜索n=11时只包含+,-,*的所有表达式,现在运行了一天左右,搜索出所有结果652566以前的表达式,总共已经搜索了233937173249个表达式.而程序还在继续运行中,也许还要运行几天.
Searching for 536423 now
        Time cost 88979,searched expressions:233472033610
Searching for 652567 now
        Time cost 89148,searched expressions:233937173249
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-10-3 12:35:31 | 显示全部楼层
而这个程序显然将不能对付n=12的情况
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-10-3 13:23:27 | 显示全部楼层


不解决状态保存问题
根本12的无法做
11的你能保证不停电么?

我那个新程序我想改成C语言
有1000GB NTFS分区应该可以运行出12的结果
中间过程完全可以做到保存状态的
只要连续7天不停电就可以了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-10-3 14:10:58 | 显示全部楼层
下面这个程序计算n=9只需要3分钟左右,不知道计算n=11需要多长时间(只考虑+,-,*三种操作符)

  1. // unreach.cpp : Defines the entry point for the console application.
  2. //

  3. #include "stdafx.h"

  4. #include <algorithm>
  5. #include <iostream>
  6. #include <vector>
  7. #include <time.h>
  8. #include <string>
  9. #include <set>
  10. #include <stdio.h>

  11. #ifdef _WIN32
  12. typedef __int64 longlong;
  13. #else
  14. typedef long long longlong;
  15. #endif
  16. using namespace std;

  17. #ifdef _DEBUG
  18. #include <assert.h>
  19. #define ASSERT(x) assert(x)
  20. #else
  21. #define ASSERT(x)
  22. #endif
  23. #define MAX_NUM 11
  24. //#define ALL_VALUES
  25. #define SMALL_SEARCH
  26. #define SEARCH_VALUE 11

  27. //enlarge CACHE_LIMIT so that some expression will be saved in memory. This
  28. //will speed the program,
  29. //but then we could not print the correct expression by expression() function.
  30. //CACHE_LIMIT should be no more than 8. I found that the speed will drop when
  31. //CACHE_LIMIT is too large
  32. #define CACHE_LIMIT 8
  33. #define MAX_BUF_SIZE 1088640000
  34. vector<bool> visited(MAX_BUF_SIZE,false);
  35. int cur_scan=1;

  36. #if CACHE_LIMIT==0
  37. //#define DISPLAY_NEW_VISIT
  38. //We could not define macro DISPLAY_NEW_VISIT when CACHE_LIMIT is non-zero, since we could not dump out expression when only result of sub-tree is cached (and sub-tree not available)
  39. //define CACHE_LIMIT to 0 and define DISPLAY_NEW_VISIT could dump out all the first expression to reach any integer number
  40. #endif

  41. #ifdef SMALL_SEARCH
  42. typedef int number;
  43. #define INTEGER(x) ((x)>=0?(x):-(x))
  44. #define IS_INTEGER(x) true
  45. #define IS_VALID(x)   true
  46. #else
  47. #define INTEGER(x) (x).get_integer()
  48. #define IS_INTEGER(x) (x).is_integer()
  49. #define IS_VALID(x)   (x).is_valid()
  50. class number{
  51.     int up;
  52.     int down;
  53. public:
  54.     number(const number& n):up(n.up),down(n.down){}
  55.     number(int n=0):up(n),down(1){}
  56.     number& operator+=(const number& n);
  57.     number& operator-=(const number& n);
  58.     number& operator*=(const number& n);
  59.     number& operator/=(const number& n);
  60.     bool is_zero()const{return down!=0&&up==0;}
  61.     bool is_valid()const{return down!=0;}
  62.     bool is_one()const{return down!=0&&up==down;}
  63.     bool operator==(const number& n)const{return
  64.         is_valid()&&n.is_valid()&&n.down*up==n.up*down;}
  65.     bool operator<(const number& n)const;
  66.     bool operator>(const number& n)const{return n<*this;}
  67.     bool operator<=(const number& n)const{return !(*this>n);}
  68.     bool operator!=(const number& n)const{return !(n==*this);}
  69.     bool operator>=(const number& n)const{return !(*this<n);}
  70.     number operator+(const number& n)const{number m(*this);return m+=n;}
  71.     number operator-(const number& n)const{number m(*this);return m-=n;}
  72.     number operator*(const number& n)const{number m(*this);return m*=n;}
  73.     number operator/(const number& n)const{number m(*this);return m/=n;}
  74.     bool is_integer()const{return down!=0&&up%down==0;}
  75.     int get_integer()const{if(is_integer())return up/down;else return -1;}
  76.     number& operator=(int n){up=n;down=1;return *this;}
  77.     int get_up()const{return up;}
  78.     int get_down()const{return down;}
  79. };

  80. number& number::operator +=(const number& n)
  81. {
  82.     up=up*n.down+down*n.up;
  83.     down*=n.down;
  84.     return *this;
  85. }

  86. number& number::operator -=(const number& n)
  87. {
  88.     up=up*n.down-down*n.up;
  89.     if(up<0)up=-up;
  90.     down*=n.down;
  91.     return *this;
  92. }

  93. number& number::operator *=(const number& n)
  94. {
  95.     up*=n.up;
  96.     down*=n.down;
  97.     return *this;
  98. }

  99. number& number::operator /=(const number& n)
  100. {
  101.     down*=n.up;
  102.     up*=n.down;
  103.     return *this;
  104. }

  105. bool number::operator <(const number &n)const
  106. {
  107.     return up*n.down<n.up*down;
  108. }
  109. #endif
  110. /*iterator to enumerate the partition of n different objects into m groups,where m is a varialbe so that the iterator will enumerate all m in range [2,n]
  111. * and sub-iterator split_iterator spliter is used to enumerator numbers of objects in each groups
  112. */
  113. class select_iterator{
  114.     int n;//total n element;
  115.     int m;//max group id; That's group 1<<8,2<<8,...,m<<8; m should be no less than 2.
  116.         //The select_iterator is used to split n elements into groups.
  117.     int select_array[MAX_NUM];///tells which group each number is located (It is select_array[x]>>8) and the order of the number inside the group (select_array[x]&255)
  118.     int sub_size[MAX_NUM]; ///sub_size[x] provides the number of elements of all groups whose group id no more than x
  119.     class split_iterator{///iterator to partition 'size' same objects into several groups (so only number of objects in each group is considered)
  120.         int split_array[MAX_NUM];///number of objects in each group
  121.         int last_index;///number of group - '1'
  122.     public:
  123.         split_iterator(int size)
  124.         {
  125.             ASSERT(size<=MAX_NUM);
  126.             if(size==1)
  127.             {
  128.                 last_index=0;
  129.                 split_array[0]=1;
  130.             }
  131.             else
  132.             {///Usually, we need partition data into at least two groups.
  133.                 last_index=1;
  134.                 split_array[0]=size-1;
  135.                 split_array[1]=1;
  136.             }
  137.         }
  138.         bool inc()///Move to the next partition
  139.         {
  140.             int i;
  141.             ASSERT(last_index<MAX_NUM);
  142.             for(i=last_index;i>=0;--i)
  143.             {
  144.                 if(split_array[i]>=2)
  145.                     break;
  146.             }
  147.             if(i==-1)
  148.             {
  149.                 int size=0;
  150.                 for(i=0;i<=last_index;++i)
  151.                     size+=split_array[i];
  152.                 if(size==1)
  153.                 {
  154.                     last_index=0;
  155.                     split_array[0]=1;
  156.                 }
  157.                 else
  158.                 {
  159.                     last_index=1;
  160.                     split_array[0]=size-1;
  161.                     split_array[1]=1;
  162.                 }
  163.                 return false;//end of search.
  164.             }
  165.             else
  166.             {
  167.                 int total;
  168.                 int last;
  169.                 last=--split_array[i];
  170.                 total=last_index-i+1;
  171.                 while(total>=last){
  172.                     split_array[++i]=last;
  173.                     total-=last;
  174.                 }
  175.                 if(total>0){
  176.                     split_array[++i]=total;
  177.                 }
  178.                 last_index=i;
  179.             }
  180.             return true;
  181.         }
  182.         friend class select_iterator;
  183.     }spliter;
  184.     void init_from_spliter();
  185. public:
  186.     select_iterator(int size);
  187.     bool inc();
  188.     int get_sub_group_count()const{return spliter.last_index+1;}
  189.     int get_sub_size(int group_id)const{return sub_size[group_id/256-1];}
  190.     int get_group_id(int num)const{return select_array[num];}
  191.     int get_main_id(int group_id)const{return group_id/256-1;}
  192.     int get_sub_id(int group_id)const{return group_id%256;}
  193.     int split_size(int i)const{return spliter.split_array[i];}
  194.     int size()const{return n;}
  195. #ifdef _DEBUG
  196.     void print()const;
  197. #endif
  198. };

  199. select_iterator::select_iterator(int size):spliter(size)
  200. {
  201.     init_from_spliter();
  202. }

  203. void select_iterator::init_from_spliter()
  204. {
  205.     int i,prev,sg,t;
  206.     n=0,m=0;
  207.     prev=-1;
  208.     for(i=0;i<=spliter.last_index;++i)
  209.     {
  210.         if(spliter.split_array[i]!=prev)
  211.         {
  212.             sub_size[m]=spliter.split_array[i];
  213.             m++;
  214.             sg=0;
  215.         }
  216.         else
  217.             sg++;
  218.         for(t=0;t<spliter.split_array[i];t++)
  219.         {
  220.             select_array[n++]=m*256+sg;
  221.         }
  222.         prev=spliter.split_array[i];
  223.     }
  224. }

  225. bool select_iterator::inc()
  226. {
  227.     int i;
  228.     int buf[MAX_NUM];
  229.     bool result;
  230.     do
  231.     {
  232.         result = next_permutation(select_array,select_array+n);///permutate all numbers until
  233.         if(!result)
  234.             break;
  235.         memset(buf,-1,sizeof(buf));
  236.         for(i=0;i<n;++i){//fill result into buf
  237.             int t=get_main_id(select_array[i]);
  238.             int q=get_sub_id(select_array[i]);
  239.             if(buf[t]<0)
  240.                 buf[t]=q;
  241.             else
  242.                 if(buf[t]>q)//invalid, all numbers in same subgroup should be ordered. Maybe we could optimize the code further
  243.                     break;
  244.         }
  245.         if(i==n)
  246.             break;
  247.     }while(true);
  248.     if(!result){///We need increase spliter when all permutation of data are searched
  249.         if(!spliter.inc())
  250.         {//set end.
  251.             init_from_spliter();
  252.             return false;
  253.         }
  254.         else
  255.         {
  256.             init_from_spliter();
  257.         }
  258.     }
  259.     return true;
  260. #if 0
  261.     for(i=n-1;i>0;--i)
  262.     {
  263.         if(select_array[i]>select_array[i-1])
  264.         {
  265.             if((select_array[i]/256)==(select_array[i-1]/256))
  266.             {//if in the same group.
  267.                 int j;
  268.                 // if(sub_size[select_array[i]/256-1]==1)
  269.                 // continue;
  270.                 for(j=i-2;j>=0;--j)
  271.                 {
  272.                     if(select_array[j]==select_array[i-1])
  273.                         break;
  274.                 }
  275.                 if(j>=0)//if found one.
  276.                     break;
  277.             }
  278.             else
  279.                 break;
  280.         }
  281.     }
  282.     if(i==0)//not found
  283.     {
  284.         if(!spliter.inc())
  285.         {//set end.
  286.             init_from_spliter();
  287.             return false;
  288.         }
  289.         else
  290.         {
  291.             init_from_spliter();
  292.         }
  293.     }
  294.     else
  295.     {
  296.         int tmp=select_array[i];
  297.         select_array[i]=select_array[i-1];
  298.         select_array[i-1]=tmp;
  299.         if(i<n-2)
  300.         {
  301.             sort(select_array+i+1,select_array+n);
  302.         }
  303.     }
  304.     return true;
  305. #endif
  306.     return result;
  307. }


  308. /*Expressions are represented by the tree iterator here.
  309. *There're two different kinds of trees according to the topmost level operator.
  310. *  the field get_prod is used to indicate whether the topmost level operators're mulitplication/division or add/sub.
  311. *  For example, expression 4*(-3)/(1+2*5) is an expression whose topmost level operators are {*,/}
  312. *   and it has three children, the first is 4, the second is (-3) and the third is expression 1+2*5
  313. *    and similarly the topmost level operators of 1+2*5 is {+}. It has two children, the first is 1 and the second 2*5, etc
  314. *  In each "tree_iterator" (a node of the tree), a spliter field is used to determine how much children nodes there're
  315. *    and how much operands there're in the (sub-)expression and how much topmost operators there're. And how those operands are partitioned to children.
  316. *  For example, if the expression is 4*(-3)/(1+2*5), there're totoal 5 operands {-3,1,2,4,5} and 2 topmost operators so that operands are partition into 3 group.
  317. *   The first child contains {4}, the second contans {-3}, the third contains {1,2,5}
  318. * Please pay attention that change ordering of children does not change the value as soon as we change the correspondent bits in pattern.
  319. * So the spliter will make sure that all groups are ordered according to number of elements to avoid those unnecessary recomputation
  320. * And the pattern will be increased by 2 instead of 1 when get_prod==0. It means that no '-' will be added to the first child.
  321. *    so that for operands set {a,b} with get_prod==0, we will only enumerate expression a+b and a-b. (b-a will not be enumerated)
  322. * And for the final result, as soon as we could reach the result -x<0, it means we could also reach x by exchange ordering of some operands.
  323. */
  324. class tree_iterator{
  325.     select_iterator spliter;
  326.     tree_iterator *next_sibling; ///pointer to the next sibling (the node whose has same parent node with this_node), NULL if it is the last child of the parent
  327.     tree_iterator *first_child;  ///pointer to the first child of the node, NULL if it is leaf. So we could use first_child->next_sibling to get the second child node
  328.     tree_iterator *current_child_iterator;///A temporary pointer used when visiting the tree. (Maybe we should not define it here)
  329.     int get_prod;   ///when get_prod!=0, all topmost operators are either * or /; otherwise all topmost operators are either + or -.
  330.     number valued;  ///field used to save the value of the expression.
  331.     int data[MAX_NUM]; ///field to save all operands used by all leaf nodes. so data[]={2,-3,1,2,5} for expression 2*(-3)/(1+2*5)
  332.     int pattern;      ///Used to determine whether an operator is * or / when get_prod!=0 and wheter an operator is + or - when get_prod==0.
  333.                         ///pattern will be treated as a bit vector. 1 for * or + and 0 for / or -.  refer to function set_values();
  334.     void build_tree();   ///Function to build the tree for an expression
  335.     void clear_child();  ///Function to remove all children(to clear the node)
  336.     void set_values();  ///set the value of the expression according to the value of children
  337.     int cached;
  338.     int finished_cached;
  339.     vector<number> caches;
  340.     int start_cache_id;
  341.     int cur_cache_id;
  342.     string prod_expression()const;  ///get the expression in string format when get_prod!=0
  343.     string sum_expression()const;   ///get the expression in string format when get_prod==0
  344.     bool no_cache_inc();   ///enumerate next expression
  345.     void no_cache_build_tree(); ///entry function to build the tree for first expression
  346.     void create_cache_file();
  347.     void read_cache_file(int offset);
  348. public:
  349.     bool inc();
  350.     tree_iterator(int n,int d[],int prod);
  351.     int size()const{return spliter.get_sub_group_count();}
  352.     ~tree_iterator(){clear_child();}
  353.     const number& get_value()const{return valued;}
  354.     string get_pattern()const;
  355.     bool debug_sum(){return true;}
  356.     bool debug_prod(){return false;}
  357.     string expression()const{if(get_prod)return prod_expression();else return
  358.         sum_expression();}
  359. };

  360. #define BUFFER_LEN 1024
  361. number buffer[BUFFER_LEN];
  362. string tree_iterator::prod_expression()const
  363. {
  364.     if(first_child==NULL)
  365.     {
  366.         char buf[10];
  367.         sprintf(buf,"%d",INTEGER(valued));
  368.         return string(buf);
  369.     }
  370.     else
  371.     {
  372.         int i;
  373.         string s;
  374.         bool first=true;
  375.         tree_iterator *child=first_child;
  376.         for(i=0;i<spliter.get_sub_group_count();++i)
  377.         {
  378.             if(pattern&(1<<i)){
  379.                 if(!first)
  380.                     s+='*';
  381.                 first=false;
  382.                 s+=child->sum_expression();
  383.             }
  384.             child=child->next_sibling;
  385.         }
  386.         child=first_child;
  387.         for(i=0;i<spliter.get_sub_group_count();++i)
  388.         {
  389.             if(!(pattern&(1<<i))){
  390.                 s+='/';
  391.                 s+=child->sum_expression();
  392.             }
  393.             child=child->next_sibling;
  394.         }
  395.         return s;
  396.     }
  397. }

  398. string tree_iterator::get_pattern()const
  399. {
  400.     if(first_child==NULL)
  401.     {
  402.         char buf[10];
  403.         sprintf(buf,"%d",INTEGER(valued));
  404.         return string(buf);
  405.     }
  406.     else
  407.     {
  408.         int i;
  409.         string s;
  410.         tree_iterator *child=first_child;
  411.         s+='[';
  412.         for(i=0;i<spliter.get_sub_group_count();++i)
  413.         {
  414.             s+=child->get_pattern();
  415.             child=child->next_sibling;
  416.         }
  417.         s+=']';
  418.         return s;
  419.     }
  420. }

  421. string tree_iterator::sum_expression()const
  422. {
  423.     if(first_child==NULL)
  424.     {
  425.         char buf[10];
  426.         sprintf(buf,"%d",INTEGER(valued));
  427.         return string(buf);
  428.     }
  429.     else
  430.     {
  431.         int i;
  432.         string s;
  433.         bool first=true;
  434.         tree_iterator *child=first_child;
  435.         s+='(';
  436.         for(i=0;i<spliter.get_sub_group_count();++i)
  437.         {
  438.             if(pattern&(1<<i)){
  439.                 if(!first)
  440.                     s+='+';
  441.                 first=false;
  442.                 s+=child->prod_expression();
  443.             }
  444.             child=child->next_sibling;
  445.         }
  446.         child=first_child;
  447.         for(i=0;i<spliter.get_sub_group_count();++i)
  448.         {
  449.             if(!(pattern&(1<<i))){
  450.                 s+='-';
  451.                 s+=child->prod_expression();
  452.             }
  453.             child=child->next_sibling;
  454.         }
  455.         s+=')';
  456.         return s;
  457.     }
  458. }

  459. bool tree_iterator::no_cache_inc()
  460. {
  461.     if(get_prod)
  462.         pattern++;
  463.     else
  464.         pattern+=2;
  465. #ifndef SMALL_SEARCH
  466.     if(pattern<(1<<size()))
  467.     {
  468.         set_values();
  469.     }
  470.     else
  471. #else
  472.         if(!get_prod&&(pattern<(1<<size()))){
  473.         set_values();
  474.         }
  475.         else
  476. #endif
  477.     {
  478.         while(current_child_iterator&&!current_child_iterator->inc())
  479.             current_child_iterator=current_child_iterator->next_sibling;
  480.         if(current_child_iterator)
  481.         {
  482.             current_child_iterator=first_child;
  483.             pattern=1;
  484.             set_values();
  485.         }
  486.         else
  487.         {
  488.             if(spliter.inc())
  489.             {
  490.                 no_cache_build_tree();
  491.             }
  492.             else
  493.             {
  494.                 no_cache_build_tree();
  495.                 return false;
  496.             }
  497.         }
  498.     }
  499.     return true;
  500. }

  501. bool tree_iterator::inc()
  502. {
  503.     if(finished_cached)
  504.     {
  505.         ++cur_cache_id;
  506.         if(cur_cache_id>=caches.size())
  507.         {
  508.             if(caches.size()==BUFFER_LEN){
  509.                 read_cache_file(start_cache_id+BUFFER_LEN);
  510.                 if(start_cache_id<0)
  511.                     return false;
  512.             }else{
  513.                 return false;
  514.             }
  515.         }else{
  516.             valued=caches[cur_cache_id];
  517.         }
  518.         return true;
  519.     }
  520.     else
  521.     {
  522.         return no_cache_inc();
  523.     }
  524. }

  525. void tree_iterator::clear_child()
  526. {
  527.     tree_iterator *child=first_child;
  528.     while(child!=NULL)
  529.     {
  530.         first_child=child->next_sibling;
  531.         delete child;
  532.         child=first_child;
  533.     }
  534.     first_child=NULL;
  535. }

  536. tree_iterator::tree_iterator(int n,int d[MAX_NUM],int prod):spliter(n)
  537. {
  538.     next_sibling=NULL;
  539.     first_child=NULL;
  540.     get_prod=prod;
  541.     cached=(n<=CACHE_LIMIT)&&(n>=3);
  542.     finished_cached=0;
  543.     current_child_iterator=NULL;
  544.     memcpy(data,d,sizeof(data));
  545.     build_tree();
  546. }

  547. void tree_iterator::set_values()
  548. {
  549.     int i;
  550.     if(get_prod)
  551.         valued=1;
  552.     else
  553.         valued=0;
  554.     tree_iterator *child=first_child;
  555.     for(i=0;i<spliter.get_sub_group_count();++i)
  556.     {
  557.         if(pattern&(1<<i))
  558.         {
  559.             if(get_prod)
  560.                 valued*=child->valued;
  561.             else
  562.                 valued+=child->valued;
  563.         }
  564.         else
  565.         {
  566.             if(get_prod)
  567. #ifdef SMALL_SEARCH
  568.                                 valued*=child->valued;
  569. #else
  570.                 valued/=child->valued;
  571. #endif
  572.             else
  573.                 valued-=child->valued;
  574.         }
  575. #ifdef ALL_VALUES
  576.                 if(IS_INTEGER(valued)){
  577.                         int x=INTEGER(valued);
  578.                         if(x<MAX_BUF_SIZE){
  579.                                 visited[x]=true;
  580.                 if(x==cur_scan)
  581.                 {
  582.                     while(cur_scan<MAX_BUF_SIZE&&visited[cur_scan])
  583.                         cur_scan++;
  584.                     cerr<<"Searching for "<<cur_scan<<" now"<<endl;
  585.                 }
  586.                         }
  587.                 }
  588. #endif
  589.         child=child->next_sibling;
  590.     }
  591.     if(get_prod&&valued==number(0)||!IS_VALID(valued))
  592.     {
  593.         pattern=((1<<size())-1);
  594.     }
  595. }

  596. void tree_iterator::no_cache_build_tree()
  597. {
  598.     int i;
  599.     int catche[MAX_NUM];
  600.     int prev=-1;
  601.     int m=0,sg,j,t;
  602.     clear_child();
  603.     if(size()==1)
  604.     {
  605.         valued=data[0];
  606.         pattern=1;
  607.         return;
  608.     }
  609.     for(i=0;i<spliter.get_sub_group_count();++i)
  610.     {
  611.         if(spliter.split_size(i)!=prev)
  612.         {
  613.             m++;
  614.             sg=0;
  615.         }
  616.         else
  617.             sg++;
  618.         t=m*256+sg;
  619.         int k;
  620.         for(k=0,j=0;j<spliter.size();++j)
  621.         {
  622.             if(spliter.get_group_id(j)==t){
  623.                 catche[k++]=data[j];
  624.             }
  625.         }
  626.         tree_iterator *child=new tree_iterator(k,catche,!get_prod);
  627.         child->next_sibling=first_child;
  628.         first_child=child;
  629.         current_child_iterator=child;
  630.         prev=spliter.split_size(i);
  631.     }
  632.     pattern=1;
  633.     set_values();
  634. }

  635. void tree_iterator::read_cache_file(int offset)
  636. {
  637.     char fName[40];
  638.     int mask=0;
  639.     int i,j;
  640.     for(i=0;i<spliter.size();i++){
  641.         mask|=1<<(data[i]-1);
  642.     }
  643.     sprintf(fName,"data\\%c%d",get_prod?'m':'a',mask);
  644.     FILE *fHandle = fopen(fName,"rb");
  645.     if(fHandle==NULL){
  646.         fprintf(stderr,"Cannot open cache file %s\n",fName);
  647.         exit(-1);
  648.     }
  649.     fseek(fHandle,offset*sizeof(number),SEEK_SET);
  650.     start_cache_id=offset;
  651.     int read_size=fread(buffer,sizeof(number),BUFFER_LEN,fHandle);
  652.     if(read_size>0){
  653.         caches.clear();
  654.         for(i=0;i<read_size;i++){
  655.             caches.push_back(buffer[i]);
  656.         }
  657.         start_cache_id=offset;
  658.         cur_cache_id=0;
  659.         valued=buffer[0];
  660.     }else{
  661.         start_cache_id=cur_cache_id=-1;
  662.     }
  663.     fclose(fHandle);
  664. }

  665. void tree_iterator::create_cache_file()
  666. {
  667.     char fName[40];
  668.     int mask=0;
  669.     int i,j;
  670.     for(i=0;i<spliter.size();i++){
  671.         mask|=1<<(data[i]-1);
  672.     }
  673.     sprintf(fName,"data\\%c%d",get_prod?'m':'a',mask);
  674.     FILE *fHandle = fopen(fName,"rb");
  675.     if(fHandle!=NULL){
  676.         fclose(fHandle);
  677.         return;
  678.     }
  679.     set<number> ncaches;
  680.     do
  681.     {
  682.         if(IS_VALID(valued))
  683.             ncaches.insert(valued);
  684.     }while(no_cache_inc());
  685.     int size=ncaches.size();
  686.     if(size==0)return;
  687.     fHandle=fopen(fName,"wb");
  688.     if(fHandle==NULL){
  689.         fprintf(stderr,"Cannot create file %s\n",fName);
  690.         exit(-1);
  691.     }
  692.     set<number>::iterator it;
  693.     i=0,j=0;
  694.     for(it=ncaches.begin();it!=ncaches.end();++it){
  695.         buffer[j]=*it;
  696.         i++,j++;
  697.         if(j==BUFFER_LEN){
  698.             j=0;
  699.             fwrite(buffer,sizeof(number)*BUFFER_LEN,1,fHandle);
  700.         }
  701.     }
  702.     if(j!=0){
  703.         fwrite(buffer,sizeof(number)*j,1,fHandle);
  704.     }
  705.     fclose(fHandle);
  706. }

  707. void tree_iterator::build_tree()
  708. {
  709.     if(!cached){
  710.         no_cache_build_tree();
  711.     }else{
  712.         no_cache_build_tree();
  713.         if(size()>1){
  714.             create_cache_file();
  715.             finished_cached=1;
  716.             read_cache_file(0);
  717.         }
  718.     }
  719. }

  720. int main()
  721. {
  722.     int a[11]={1,2,3,4,5,6,7,8,9,10,11};
  723.     longlong count=0;
  724.     time_t starttime=time(NULL);
  725.     {
  726.         tree_iterator it(SEARCH_VALUE,a,1);
  727.         do
  728.         {
  729.             if(IS_INTEGER(it.get_value())){
  730.                 int value=INTEGER(it.get_value());
  731.                 if(value<0)value=-value;
  732. #ifdef DISPLAY_NEW_VISIT
  733.                 if(value<MAX_BUF_SIZE&&!visited[value]){
  734.                     cout<<value<<'='<<it.expression()<<endl;
  735.                 }
  736. #endif
  737.                 visited[value]=true;
  738.                 if(value==cur_scan)
  739.                 {
  740.                     while(cur_scan<MAX_BUF_SIZE&&visited[cur_scan])
  741.                         cur_scan++;
  742.                     cerr<<"Searching for "<<cur_scan<<" now"<<endl;
  743.                     cerr<<'\t'<<"Time cost "<<time(NULL)-starttime;
  744.                     cerr<<','<<"searched expressions:"<<count+1<<endl;
  745.                 }
  746.             }
  747.             count++;
  748.         }while(it.inc());
  749.     }
  750.     {
  751.         tree_iterator it(SEARCH_VALUE,a,0);
  752.         do
  753.         {
  754.             if(IS_INTEGER(it.get_value())){
  755.                 int value=INTEGER(it.get_value());
  756.                 if(value<0)
  757.                     value=-value;
  758. #ifdef DISPLAY_NEW_VISIT
  759.                 if(value<MAX_BUF_SIZE&&!visited[value]){
  760.                     cerr<<value<<'='<<it.expression()<<endl;
  761.                 }
  762. #endif
  763.                 visited[value]=true;
  764.                 if(value==cur_scan)
  765.                 {
  766.                     while(cur_scan<MAX_BUF_SIZE&&visited[cur_scan])
  767.                         cur_scan++;
  768.                     cerr<<"Searching for "<<cur_scan<<" now"<<endl;
  769.                     cerr<<'\t'<<"Time cost "<<time(NULL)-starttime;
  770.                     cerr<<','<<"searched expressions:"<<count<<endl;
  771.                 }
  772.             }
  773.             count++;
  774.         }while(it.inc());
  775.     }
  776.     cerr<<"Total expressions searched:"<<count<<endl;
  777.     cerr<<"Total time cost "<<time(NULL)-starttime<<endl;
  778.     cout<<"The first integer not reached is "<<cur_scan<<endl;
  779.     return 0;
  780. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-10-3 14:34:01 | 显示全部楼层
和你上次发的有什么区别?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-10-3 14:35:09 | 显示全部楼层
好像递增极端迅速
9的和10的应该至少差9*10倍
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-10-3 15:17:08 | 显示全部楼层
我的程序精简了输出
7的共413M输出
相当于51609600个表达式

估计8在2.3G
9在166.5G
所以似乎还是不好做
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-10-3 18:35:57 | 显示全部楼层
原帖由 无心人 于 2008-10-3 14:34 发表
和你上次发的有什么区别?

保存了部分中间结果到文件
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-10-3 20:14:13 | 显示全部楼层
0

我想,这个问题后面的是前面的规模的n(n-1)倍
所以11的需要10的110倍运行时间
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-4-27 11:34 , Processed in 0.738751 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表