迭代差异

时间:2014-03-27 20:23:51

标签: c++ algorithm optimization

这是一个蠢事问题。它有效,但它太慢了。

以下是问题:

迭代差异

  

您将获得N个非负整数的列表a(1),a(2),...,   一个)。您可以用新列表替换给定列表:第k个条目   新列表是a(k) - a(k + 1)的绝对值,包围在   列表的结尾(新列表的第k个条目是绝对的   a(N) - a(1)的值。这个替换的迭代次数是多少   需要到达一个列表,其中每个条目是相同的整数?

例如,让N = 4从列表(0 2 5 11)开始。连续的迭代是:

2 3 6 11
1 3 5 9
2 2 4 8
0 2 4 6
2 2 2 6
0 0 4 4
0 4 0 4
4 4 4 4

因此,在这个例子中需要8次迭代。

输入

  

输入将包含许多测试用例的数据。对于每个案例,   会有两行输入。第一行将包含   整数N(2 <= N <= 20),列表中的条目数。该   第二行将包含整数列表,由一个空格分隔   空间。输入结束将由N = 0表示。

输出

  

对于每种情况,都会有一行输出,指定大小写   数字和迭代次数,采用示例中显示的格式   输出。如果列表在1000之后没有达到所需的形式   迭代,打印'未达到'。

示例输入

4
0 2 5 11
5
0 2 5 11 3
4
300 8600 9000 4000
16
12 20 3 7 8 10 44 50 12 200 300 7 8 10 44 50
3
1 1 1
4
0 4 0 4
0

示例输出

Case 1: 8 iterations
Case 2: not attained
Case 3: 3 iterations
Case 4: 50 iterations
Case 5: 0 iterations
Case 6: 1 iterations

我不知道如何做到更快。我尝试使用数组,但是在尝试分配内存并将一个数组设置为另一个数组时遇到了各种各样的问题。

如何让它更快?这是我的代码:

#include <iostream>
#include <vector>
#include <cmath>
#include <sstream>
#include <string>

using namespace std;

bool checker(vector<int>& nums2) {
   int n = nums2[0];
   for (int i = 1; i < nums2.size(); i++)
   {
      if (n != nums2[i])
         return false;
   } 
   return true;
}

vector<int> iterate(vector<int>& nums, int& iter, bool& attained) {
   if (iter == 1000) {
      attained = false;
      return nums;
   }
   vector<int> nums2;

   for (int i = 0; i < nums.size(); i++) {
      if (i == nums.size() - 1)
         nums2.push_back((int)abs((double)nums[i] - (double)nums[0]));
      else
         nums2.push_back((int)abs((double)nums[i] - (double)nums[i + 1]));
   }

   iter++;
   return nums2;
}

int main()
{
   int N = -1, count = 1;

   while (1) {
      int num = 0;
      vector<int> nums;
      string List = "";
      stringstream ss;
      cin >> N;

      if (N == 0)
         break;

      cin.ignore();
      cin.clear();
      getline(cin, List);

      ss << List;

      while (ss >> num) {
         nums.push_back(num);
      }

      int iterations = 0;
      bool attained = true;
      while (!checker(nums)) {
         nums = iterate(nums, iterations, attained);
      }

      if (!attained)
         cout << "case " << count << ": not attained";
      else 
         cout << "case " << count << ": " << iterations << " iterations" << endl;
      count++;
   }
}

3 个答案:

答案 0 :(得分:0)

我修好了。这是主函数中的while循环的问题。条件是:

    while (!checker(nums)) { ... }

它将保持在循环中并重复调用迭代函数,因为如果它不可达,则检查器将始终为false。所以将条件改为:

    while (!checker(nums) && attained) { ... }
如果无法实现,

会破坏循环。 基本上,它只是一遍又一遍地坚持做同样的事情;它实际上并不慢。 谢谢,谢,你的答案。

答案 1 :(得分:-1)

如果您希望它更快地,您应该调试阵列变化以避免矢量分配。如果您希望它更快地 lot ,您需要对问题进行一些分析以找到更好的算法。例如,如果您看到两次相同的列表,那么您将处于循环中并且将超过1000次迭代。如果旋转列表,结果将是相同的,在检查重复列表时可以考虑。

答案 2 :(得分:-1)

您的实现在我的主流lapton上执行了25ms内的1000次迭代。修正了一个,因为有一个bug而且案例2将永远执行。

要做得更快,您可以重复使用相同的向量并对其进行修改,您的iterator()函数签名将如下所示:

void iterate(vector<int>& nums); 

这个版本在我的机器上需要7ms,因为它不会在循环中分配内存。