描述
题解
遇见这种题,直观感觉就是规律题,所以先打表找规律……
然后发现,可以找到16一循环的规律,当然,这个循环不是完美的循环,第16位并不是固定的,可是感觉并不是太直观,然后观察第16位,忽然发现这里也存在一定的周期关系,于是直接打64的倍数……
然后,发现不光16,只要往后边推,64、256、……都存在一定的周期性,那么我们应该选取那个周期性比较好呢?
然后发现题意,数据上限是50个,那么我们采用64的周期是比较合适的,然后暴力匹配就行了,这里需要注意一点的是,防越界问题,因为这是周期性关系,所以除了第64个需要特判外,还要取模,防止下标越界。
代码
#include <iostream>
using namespace std;
const int MAXN = 55;
const int MAXM = MAXN + 10;
const int CYCL = 64;
int power[MAXM] = {1};
int tail[MAXM];
int d[MAXN];
int N;
int ans;
void init()
{
for (int i = 1; i < MAXM; i++)
{
power[i] = power[i - 1] * 2;
}
for (int i = 1; i < MAXM; i++)
{
int res = i & (-i);
for (int j = 0; j < MAXN; j++)
{
if (power[j] == res)
{
tail[i - 1] = j;
break;
}
}
}
return ;
}
void solve(int n)
{
if (n > N)
{
return ;
}
for (int i = 0; i < N - n + 1; i++)
{
for (int j = 0; j < CYCL; j++)
{
if (d[i] == tail[j] || (j == CYCL - 1 && d[i] >= tail[CYCL - 1]))
{
bool flag = true;
for (int k = 1; k < n; k++)
{
if (j + k == CYCL - 1 && d[i + k] >= tail[CYCL - 1])
{
continue;
}
if (d[i + k] != tail[(j + k) % CYCL])
{
flag = false;
break;
}
}
if (flag)
{
ans++;
break;
}
}
}
}
solve(n + 1);
return ;
}
int main(int argc, const char * argv[])
{
// freopen("/Users/zyj/Desktop/input.txt", "r", stdin);
init();
int T;
cin >> T;
while (T--)
{
cin >> N;
ans = N;
for (int i = 0; i < N; i++)
{
scanf("%d", d + i);
}
solve(2);
cout << ans << '\n';
}
return 0;
}