Time limit: 0.5 seconds
Memory limit: 256 megabytes
Zayin and Taotao are poor in mathematics. In order to improve their math skill, they count numbers together today. They write a number every second in the ascending order, such as 0,
1
,
2
,
3, etc. However, they can’t recognize all the Arabic letters. As a result, they both ignore numbers containing the Arabic letters they don’t know. For example, if Zayin only knows 0 and 1, he will write down 0,
1
,
10
,
11, etc.
For each Arabic letter, you know whether Zayin and Taotao can recognize it. Both Zayin and Taotao can recognize at least two Arabic letters. Besides, you know the number Zayin will write in x
-th second.
Can you write a program to calculate the number that Taotao will write at this time?
Input
The fifirst line of input contains an integer
T
(1
≤
T
≤
1e
4
), denoting the number of test cases.
For each test case, you will get a boolean array
A
which contains exactly 10 booleans in the fifirst line.
If
A
i
= 1 (the index starts at 0), Zayin can recognize Arabic letter
i
. Otherwise, Zayin can’t recognize Arabic letter i
.
Similarly, you will get a boolean array
B
which contains exactly 10 booleans in the second line. If
B
i
= 1 (the index starts at 0), Taotao can recognize Arabic letter i
. Otherwise, Taotao can’t recognize Arabic letter i
.
In the third line, you will get the number Zayin will write in
x
-th (
x <
2^
64
) second.
Output
For each test case, you should write down the number that Taotao will write in
x
-th second in a single line.
样例输入:
1
1 0 1 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0
20
样例输出:
10
未完成:
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
ll pow2(ll a, ll b)
{
ll res = 1;
while (b)
{
if (b % 2 != 0)
{
res *= a;
}
a *= a;
b /= 2;
}
return res;
}
int main()
{
// system("chcp 65001");
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while (T--)
{
int A[16] = {0}, B[16] = {0}, a = 0, b = 0;
map<int, int> Ahave;
map<int, int> Bhave;
for (int i = 0; i < 10; i++)
{
cin >> A[i];
if (A[i])
{
Ahave[i] = a; // Ahave[i]代表i前面有a个数可以识别
a++;
}
}
for (int i = 0; i < 10; i++)
{
cin >> B[i];
if (B[i])
{
Bhave[i] = b;
b++;
}
}
string number_xth; // 这个数也可能爆ll,要用string
cin >> number_xth;
ll len = number_xth.length();
ll x = 0;
if (A[0] == 0) // 不能识别0的情况
{
x = (a - pow2(a, len)) / (1 - a); // 到len-1位数为止一共有这些数
}
ll pre = 1;
for (int i = len - 1; i >= 0; i--) // 对number的每一位,判断这一位前面有几个数,相当于进制转换,这个len应该不会很大
{
int t = number_xth[i] - '0';
x += Ahave[t] * pre;
pre *= a;
}
if (Bhave[0] != 0)
x++;
printf("求第%d个数\n", x);
// // 二分枚举res是几位数,即求第一个小于等于x的t对应的mid+1
// ll l = 1, r = 19; // 取ll的上限1e19
// ll t;
// printf("b = %d\n", b);
// while (l < r)
// {
// // printf("left = %d, right = %d\n", l, r);
// ll mid = (l + r + 1) / 2;
// // printf("mid = %d\n", mid);
// if (B[0] == 0)
// {
// t = (b - pow2(b, mid)) / (1 - b);
// }
// else
// {
// t = pow2(b, mid - 1);
// }
// // printf("t = %d\n",t);
// if (t >= x)
// {
// r = mid - 1;
// }
// else
// {
// l = mid;
// }
// }
// len = r;
// if (B[0] == 0)
// {
// t = (b - pow2(b, len)) / (1 - b);
// }
// else
// {
// t = pow2(b, len - 1);
// }
// x -= t;
// printf("len = %d\n", len);
vector<int> res;
while (x)
{
ll cur = x % b;
res.push_back(cur);
x /= b;
}
for (int i = res.size() - 1; i >= 0; i--)
{
cout << res[i];
}
cout << endl;
}
cout << endl;
return 0;
}