当前所在位置:珠峰网资料 >> 计算机 >> 计算机等级考试 >> 正文
计算机二级C语言辅导--回溯法之数的划分
发布时间:2010/1/8 22:33:55 来源:城市学习网 编辑:海蓝
  #include <iostream>
  #include <vector>
  using namespace std;
  long long r[221][11][221];
  int f(int m, int n, int c)
  {
  //只要分成两列,在首位数字确定的情况下只可能有一种分法
  if( n <= 2 )
  return 1;
  int i;
  int result = 0;
  int max = (m - c) / (n - 1);//首位数字最大值
  int tmp = 0;
  for(i = c; i <= max; i++)
  {
  if( r[m - c][n - 1][i] == 0 )
  {
  r[m - c][n - 1][i] = f(m - c, n - 1, i);
  }
  result += r[m - c][n - 1][i];
  }
  r[m][n][c] = result;
  return result;
  }
  vector<int> Record(int m, int n, int k)
  {
  vector<int> s;
  int i;
  for( i = 1; i <= m / n; i++)
  {
  f(m, n, i);//按需调用
  if(r[m][n][i] < k)
  {
  k -= r[m][n][i];//如果当前的次序不够k, 把k减少,相当于从i + 1 后找第k'名
  }
  else
  {
  s.push_back(i);//存储路径
  if( n == 2 )
  {
  s.push_back(m - i);//列数为2的时候,存储两列,退出
  break;
  }
  else
  {
  m -= i;//修改m为首位后面的数字和
  --n;//行数减少了1
  --i;//为了保持i不变,这里减少了1
  }
  }
  }
  return s;
  }
  void Output(vector<int> seq)
  {
  int size = seq.size();
  if(size > 0 )
  {
  cout << seq[0] ;
  for(int i = 1; i < size; i++)
  cout << ' ' << seq[i];
  cout << endl;
  }
  }
  int main()
  {
  int m, n, k;
  while( cin >> m >> n >> k )
  {
  Output(Record(m, n, k));
  }
  return 0;
  }
广告合作:400-664-0084 全国热线:400-664-0084
Copyright 2010 - 2017 www.my8848.com 珠峰网 粤ICP备15066211号
珠峰网 版权所有 All Rights Reserved