fork(1) download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class
  5. DividePatternGeneratorException
  6. {
  7. }
  8. ;
  9.  
  10. class
  11. DividePatternGenerator
  12. {
  13. private: /* private fields */
  14.  
  15. int *
  16. _list
  17. ;
  18.  
  19. int
  20. _size
  21. ;
  22.  
  23. int
  24. _division
  25. ;
  26.  
  27. int
  28. _min
  29. ;
  30.  
  31. int
  32. _max
  33. ;
  34.  
  35. int
  36. _count
  37. ;
  38.  
  39. private: /* private constructors */
  40.  
  41. DividePatternGenerator
  42. (
  43. )
  44. ;
  45.  
  46. private: /* private methods */
  47.  
  48. void
  49. init
  50. (
  51. )
  52. {
  53. if
  54. ( _size < 2
  55. || _division < 2
  56. || _size < _division
  57. || _size < _min * _division
  58. || _max < _min
  59. || _size < _max + _min * (_division - 1 )
  60. )
  61. {
  62. throw DividePatternGeneratorException();
  63. }
  64. _list = new int[_division];
  65. for
  66. ( int i = 0
  67. ; i < _division
  68. ; i++
  69. )
  70. {
  71. _list[i] = 0;
  72. }
  73. }
  74.  
  75. public: /* public constructors */
  76.  
  77. DividePatternGenerator
  78. ( int size
  79. , int division
  80. , int minsize
  81. , int maxsize
  82. )
  83. : _size(size)
  84. , _division(division)
  85. , _min(minsize)
  86. , _max(maxsize)
  87. , _count(0)
  88. {
  89. init();
  90. }
  91.  
  92. DividePatternGenerator
  93. ( int size
  94. , int division
  95. )
  96. : _size(size)
  97. , _division(division)
  98. , _min(1)
  99. , _max(size - division + 1)
  100. , _count(0)
  101. {
  102. init();
  103. }
  104.  
  105. DividePatternGenerator
  106. ( int size
  107. )
  108. : _size(size)
  109. , _division(2)
  110. , _min(size / 2)
  111. , _max(size - 1)
  112. , _count(0)
  113. {
  114. init();
  115. }
  116.  
  117. public: /* public destructor */
  118.  
  119. ~DividePatternGenerator
  120. (
  121. )
  122. {
  123. delete [] _list;
  124. }
  125.  
  126. public: /* public methods */
  127.  
  128. int
  129. length
  130. (
  131. )
  132. const
  133. {
  134. return _division;
  135. }
  136.  
  137. int
  138. size
  139. (
  140. )
  141. const
  142. {
  143. return _size;
  144. }
  145.  
  146. int
  147. count
  148. (
  149. )
  150. const
  151. {
  152. return _count;
  153. }
  154.  
  155. const int *
  156. list
  157. (
  158. )
  159. const
  160. {
  161. return _list;
  162. }
  163.  
  164. const int *
  165. next
  166. (
  167. )
  168. {
  169. int n, d, p;
  170. bool f;
  171.  
  172. if
  173. ( _count == 0
  174. )
  175. {
  176. _list[0] = _min;
  177. p = 1;
  178. d = _division - 1;
  179. n = _size - _min;
  180. f = false;
  181. }
  182. else
  183. {
  184. p = _division - 2;
  185. d = 2;
  186. n = _list[p] + _list[p + 1];
  187. f = true;
  188. }
  189.  
  190. for
  191. (
  192. ;
  193. ;
  194. )
  195. {
  196. if
  197. ( d == 1
  198. )
  199. {
  200. if
  201. ( n <= _max
  202. )
  203. {
  204. _list[p] = n;
  205. n = 0;
  206. d = 0;
  207. _count++;
  208. break;
  209. // OK
  210. // exit loop
  211. }
  212. else
  213. {
  214. d++;
  215. p--;
  216. n += _list[p];
  217. f = true;
  218. }
  219. }
  220. else
  221. {
  222. int m;
  223. if
  224. ( f == true
  225. )
  226. {
  227. m = _list[p] + 1;
  228. f = false;
  229. }
  230. else
  231. {
  232. m = _list[p - 1];
  233. }
  234. if
  235. ( m * d > n
  236. )
  237. {
  238. if
  239. ( p == 0
  240. )
  241. {
  242. _count = 0;
  243. _list[0] = _min;
  244. p = 1;
  245. d = _division - 1;
  246. n = _size - _min;
  247. // all pattern had gone
  248. // reset pattern
  249. }
  250. else
  251. {
  252. d++;
  253. p--;
  254. n += _list[p];
  255. f = true;
  256. }
  257. }
  258. else
  259. {
  260. _list[p] = m;
  261. n -= m;
  262. d--;
  263. p++;
  264. }
  265. }
  266. }
  267. return _list;
  268. }
  269. }
  270. ;
  271.  
  272.  
  273. int
  274. main
  275. (
  276. )
  277. {
  278. try
  279. {
  280. DividePatternGenerator gen(10, 5);
  281.  
  282. cout << "10個を5分割するパターンのリストを作る" << endl;
  283.  
  284. cout << "size: " << gen.size() << endl;
  285.  
  286. for
  287. ( int j = 0
  288. ; j < 10
  289. ; j++
  290. )
  291. {
  292. const int* list = gen.next();
  293. cout << "[" << gen.count() << "] ";
  294. for
  295. ( int i = 0
  296. ; i < gen.length()
  297. ; i++
  298. )
  299. {
  300. cout << list[i] << " ";
  301. }
  302. cout << endl;
  303. }
  304.  
  305. cout << "* * * * * * * * * * * * * *" << endl;
  306.  
  307. DividePatternGenerator gen2(10, 3);
  308.  
  309. cout << "10個を3分割するパターンのリストを作る" << endl;
  310.  
  311. cout << "size: " << gen2.size() << endl;
  312.  
  313. for
  314. ( int j = 0
  315. ; j < 10
  316. ; j++
  317. )
  318. {
  319. const int* list = gen2.next();
  320. cout << "[" << gen2.count() << "] ";
  321. for
  322. ( int i = 0
  323. ; i < gen2.length()
  324. ; i++
  325. )
  326. {
  327. cout << list[i] << " ";
  328. }
  329. cout << endl;
  330. }
  331. }
  332. catch
  333. ( DividePatternGeneratorException& ex
  334. )
  335. {
  336. cout << "Exception" << endl;
  337. }
  338.  
  339. return 0;
  340. }
  341.  
  342.  
  343.  
  344.  
Success #stdin #stdout 0s 3480KB
stdin
Standard input is empty
stdout
10個を5分割するパターンのリストを作る
size: 10
[1] 1 1 1 1 6 
[2] 1 1 1 2 5 
[3] 1 1 1 3 4 
[4] 1 1 2 2 4 
[5] 1 1 2 3 3 
[6] 1 2 2 2 3 
[7] 2 2 2 2 2 
[1] 1 1 1 1 6 
[2] 1 1 1 2 5 
[3] 1 1 1 3 4 
* * * * * * * * * * * * * *
10個を3分割するパターンのリストを作る
size: 10
[1] 1 1 8 
[2] 1 2 7 
[3] 1 3 6 
[4] 1 4 5 
[5] 2 2 6 
[6] 2 3 5 
[7] 2 4 4 
[8] 3 3 4 
[1] 1 1 8 
[2] 1 2 7