TC SRM 632-500 Potential Geometric Sequence

Problem Statement

We have a sequence of N positive integers: a[0] through a[N-1].You do not know these integers.All you know is the number of trailing zeros in their binary representations.You are given a int[] d with N elements.For each i, d[i] is the number of trailing zeros in the binary representation of a[i].

For example, suppose that a[0]=40.In binary, 40 is 101000 which ends in three zeros.Therefore, d[0] will be 3.

You like geometric sequences.(See the Notes section for a definition of a geometric sequence.)You would like to count all non-empty contiguous subsequences of the sequence a[0], a[1], ..., a[N-1] that can be geometric sequences (given the information you have in d).

More precisely:For each pair (i,j) such that 0 <= i <= j <= N-1, we ask the following question: "Given the values d[i] through d[j], is it possible that the values a[i] through a[j] form a geometric sequence?"

For example, suppose that d = {0,1,2,3,2}.For i=0 and j=3 the answer is positive: it is possible that the values a[0] through a[3] are {1,2,4,8} which is a geometric sequence.For i=1 and j=4 the answer is negative: there is no geometric sequence with these numbers of trailing zeros in binary.

Compute and return the number of contiguous subsequences of a[0], a[1], ..., a[N-1] that can be geometric sequences.

Definition

  • Class PotentialGeometricSequence
  • Method numberOfSubsequences
  • Parameters vector<int>
  • Returns int
  • Method signature int numberOfSubsequences(vector<int> d)
(be sure your method is public)

Limits

  • Time limit (s) 2.000
  • Memory limit (MB) 256

Notes

  • A geometric sequence is any sequence g[0], g[1], ..., g[k-1] such that there is a real number q (the quotient) with the property that for each valid i, g[i+1] = g[i]*q. For example, {1,2,4,8} is a geometric sequence with q=2, {7,7,7} is a geometric sequence with q=1, and {18,6,2} is a geometric sequence with q=1/3.

Constraints

  • N will be between 1 and 50, inclusive.
  • d will contain exactly N elements.
  • Each element of d will be between 0 and 100, inclusive.

Test cases

    • d { 0, 1, 2 }
    Returns 6
    One possibility is that a[0]=3, a[1]=6, and a[2]=12. In this case, all contiguous subsequences of this sequence are geometric.
    • d { 1, 2, 4 }
    Returns 5
    All one-element and two-element subsequences are geometric. The entire sequence cannot be geometric.
    • d { 3, 2, 1, 0 }
    Returns 10
    • d { 1, 2, 4, 8, 16 }
    Returns 9
    • d { 1, 3, 5, 5, 5, 5, 64, 4, 23, 2, 3, 4, 5, 4, 3 }
    Returns 37
解析:这个题观察规律发现d[i]到d[j]是个等差数列(公差可以是0)那么a[i]到a[j]就可以构成等比数列。至于原理我还不知道,通过样例观察出来的结论= =

#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <typeinfo>
#include <fstream>

using namespace std;

class PotentialGeometricSequence {
    public:
    int numberOfSubsequences(vector<int> d) {
		int ans=0;
		for(int i=0;i<d.size()-1;i++)
		{
			ans++;
			int sd=d.at(i+1)-d.at(i);
			for(int j=i+2;j<d.size();j++) if(d.at(j)-d.at(j-1)==sd) ans++;else break;
		}
        return ans+d.size();
    }
};

// CUT begin
ifstream data("PotentialGeometricSequence.sample");

string next_line() {
    string s;
    getline(data, s);
    return s;
}

template <typename T> void from_stream(T &t) {
    stringstream ss(next_line());
    ss >> t;
}

void from_stream(string &s) {
    s = next_line();
}

template <typename T> void from_stream(vector<T> &ts) {
    int len;
    from_stream(len);
    ts.clear();
    for (int i = 0; i < len; ++i) {
        T t;
        from_stream(t);
        ts.push_back(t);
    }
}

template <typename T>
string to_string(T t) {
    stringstream s;
    s << t;
    return s.str();
}

string to_string(string t) {
    return "\"" + t + "\"";
}

bool do_test(vector<int> d, int __expected) {
    time_t startClock = clock();
    PotentialGeometricSequence *instance = new PotentialGeometricSequence();
    int __result = instance->numberOfSubsequences(d);
    double elapsed = (double)(clock() - startClock) / CLOCKS_PER_SEC;
    delete instance;

    if (__result == __expected) {
        cout << "PASSED!" << " (" << elapsed << " seconds)" << endl;
        return true;
    }
    else {
        cout << "FAILED!" << " (" << elapsed << " seconds)" << endl;
        cout << "           Expected: " << to_string(__expected) << endl;
        cout << "           Received: " << to_string(__result) << endl;
        return false;
    }
}

int run_test(bool mainProcess, const set<int> &case_set, const string command) {
    int cases = 0, passed = 0;
    while (true) {
        if (next_line().find("--") != 0)
            break;
        vector<int> d;
        from_stream(d);
        next_line();
        int __answer;
        from_stream(__answer);

        cases++;
        if (case_set.size() > 0 && case_set.find(cases - 1) == case_set.end())
            continue;

        cout << "  Testcase #" << cases - 1 << " ... ";
        if ( do_test(d, __answer)) {
            passed++;
        }
    }
    if (mainProcess) {
        cout << endl << "Passed : " << passed << "/" << cases << " cases" << endl;
        int T = time(NULL) - 1409915671;
        double PT = T / 60.0, TT = 75.0;
        cout << "Time   : " << T / 60 << " minutes " << T % 60 << " secs" << endl;
        cout << "Score  : " << 500 * (0.3 + (0.7 * TT * TT) / (10.0 * PT * PT + TT * TT)) << " points" << endl;
    }
    return 0;
}

int main(int argc, char *argv[]) {
    cout.setf(ios::fixed, ios::floatfield);
    cout.precision(2);
    set<int> cases;
    bool mainProcess = true;
    for (int i = 1; i < argc; ++i) {
        if ( string(argv[i]) == "-") {
            mainProcess = false;
        } else {
            cases.insert(atoi(argv[i]));
        }
    }
    if (mainProcess) {
        cout << "PotentialGeometricSequence (500 Points)" << endl << endl;
    }
    return run_test(mainProcess, cases, argv[0]);
}
// CUT end



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值