检查“1”或“0”是否位于10序列(1101001000 ...)C ++

时间:2015-11-05 16:38:29

标签: c++

所以我有这个问题需要解决。一个接一个地写入10的幂序列,开头看起来像这样:1101001000 ...检查给定数字是否对应于此序列中的“1”或“0”。 第一个输入: N数字,用于定义有多少测试。 第二次输入: N行,带有要检查的数字。 输出:N个数字为“1”或“0”。 例如:

  

输入:

     

4

     

3

     

14

     

7

     

6

     

输出:

     

0 0 1 0

所以我得到了这个:

#include <iostream>

using namespace std;

int main() {
    int a, b;
    cin >> a;
    for (int k = 1; k <= a; k++){
        cin >> b;
        int flag = 0;
        for (int s = 1; s <= b; s++){
            if (((s * (s - 1)) / 2) + 1 == b){
                flag = 1;
                break;
            }
        }   
        if (flag == 1)
            cout << "1" << endl;
        else
            cout << "0" << endl;
    }
    return 0;
}

并且它应该可以工作,但我学校的调试器/测试人员说超出了时间限制,要么程序花费太长时间,要么程序永远不会结束,我无能为力。一个月前开始编程所以请不要花哨。

((s *(s-1))/ 2)+1在序列中给出“1”个位置。

1 个答案:

答案 0 :(得分:4)

你的解决方案很聪明。您的想法是通过使用闭合公式来跳过二进制字符串中的所有1,以获得序列中s - th 1的位置。如果序列的b为1,则可以通过迭代s来快速找到,因为对于某些 s,条件((s * (s - 1)) / 2) + 1 == b变得真实。到目前为止还可以。

但是,如果序列在b处为0,则该条件永远不会为真。你永远不会打1,你只能在你的情况下检查。因此,如果s的值为< b,则公式为> b,而下一个值为b,则跳过s。但是你继续s > b的for循环直到> b,这是花费很多时间的方式。

简而言之,您需要检查b。如果是这种情况,您知道序列在break;处为0。在这种情况下,只需s就可以了。

您甚至可以通过将公式反转为直接从b计算s来改善这一点。为此,解决s的公式。 That gives you s = 0.5*(sqrt(8*b-7)-1)(请注意,否定解决方案无关紧要)。这是对实数的计算,因此您需要浮点数,结果也是浮点数。

如果s证明是一个整数,那么你会得到1,否则为0。但是将结果检查为积分是容易出错的(浮点运算会引入一些可预测但不可避免的舍入误差)。因此,我建议使用正向公式(您已经拥有的公式)以及此反转公式的向下舍入和舍入结果。换句话说,使用浮点反转公式猜测s,使用此s检查两个可能的候选项,以便对您的前向公式进行积分float guess_s = 0.5*(sqrt(8*b-7)-1); int s1 = floor(guess_s); // rounded down int s2 = s1 + 1; // rounded up

s1

然后使用您的公式检查s2if ( ((s1 * (s1 - 1)) / 2) + 1 == b || ((s2 * (s2 - 1)) / 2) + 1 == b ) cout << "1" << endl; else cout << "0" << endl;

= link_to "Delete My Account", user_path(@user), :method=>:delete, :confirm => "Are you sure to delete your account?"