2021CCPC威海热身赛_Problem C. Count

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;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值