首页 > 试题广场 >

Bittttttts

[编程题]Bittttttts
  • 热度指数:2519 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解

现在有q个询问,每次询问想问你在[l,r]区间内,k进制表示中,k-1的数量最多的数是哪个数。比如当k=2时,9的二进制就是1001,那么他就有21.


输入描述:
第一行一个q,表示有q组询问。

接下来q行,每行三个整数k,l,r,分别表示进制数,查询的数字,以及查询的范围。

满足1<=q<=100000,2<=k<=16,1<=l<=r<=10^16


输出描述:
对于每组询问,输出答案。如果有多个答案,请输出最小的。
示例1

输入

1
8 1 100

输出

63

用java写的,最后还是通过了 但速度有点慢。这都不是关键,具体讲解一下思路。
首先将start(我用start和end分别表示左右的边界)转换成k进制。将转换后的每一位都存在arraylist中(数组和linklist也可以,自己选)。然后从低位往高位依次将每一位变成(k-1)。在变换之前,首先看看能不能变,能变则变,不能变表示超过了end,这个时候直接跳出即可。

import java.util.ArrayList;
import java.util.Scanner;
public class Main {

    public static long minNum(int k, long start, long end) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        long tmp = start;
        while (tmp != 0) {
            long rest = tmp % k;
            list.add((int) rest);
            tmp = tmp / k;
        }
        long sum = 1;
        for (int i = 0; i < list.size(); i++) {
            long num = list.get(i);
            num = k - 1 - num;
            long size = (long) (num * sum);
            if (start + size <= end) {
                start = start + size;
            } else {
                return start;
            }
            sum = sum * k;
        }
        while (start < end) {
            long size = (long) ((k - 1) * sum);
            if (start + size <= end) {
                start = start + size;
            } else {
                return start;
            }
            sum = sum * k;
        }
        return start;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int time = in.nextInt();
            for (int i = 0; i < time; i++) {
                int k = in.nextInt();
                long start = in.nextLong();
                long end = in.nextLong();
                System.out.println(minNum(k, start, end));
            }
        }
    }
}
发表于 2019-08-07 22:30:37 回复(12)
#include <iostream>
#include <vector>

using namespace std;

// 思路 先把 low和high都转换成k进制数,然后寻找在[low, high]之间k进制中k-1最多的数,为方便k=10
// 123 123456 -> 099999:二者位数不同时, 把high最高位变成0,后面其他位置为9即可
// 123 999999 -> 999999 需要注意high所有位都为9时,ans = high, 玛德这种情况找了好久才找到,sad
// 123456 123556 -> 123499 二者位数相同时,把low从位数不同的下一位到最后置为9即可
// 123456 123999 -> 123999 需要注意high在不同位往后都为9时, ans =  high

// 把number转换成k进制存在vector中,高位放在后面 如十进制的12345 -> 54321
void convertk(vector<int> &v, long number, int k) {
    while (number) {
        v.push_back(number % k);
        number /= k;
    }
}

long query(long low, long high, int k) {
    if (low == high)
        return low;
    vector<int> vecLow, vecHigh, vecAns;
    convertk(vecLow, low, k);
    convertk(vecHigh, high, k);
    int i = vecHigh.size()-1, j = vecLow.size()-1;
    while (i == j && vecHigh[i] == vecLow[j]) {
        i--;
        j--;
    }
    if (i > j) { // low和high位数不同时
        bool allLeftIsK_1 = false;
        if (vecHigh[i] == k-1) {
            allLeftIsK_1 = true;
            for (int l = i; l >= 0; l--) {
                if (vecHigh[l] != k-1) {
                    allLeftIsK_1 = false;
                    break;
                }
            }
        }
        if (allLeftIsK_1) //123 999999 -> 999999 high 所有位上都是k-1, ans = high
            vecAns = vecHigh;
        else {      //123 123456 -> 099999 最高位置0,其他位置k-1
            vecAns = vecHigh;
            vecAns[i] = 0; // 最高位置0
            i--;
            while (i >= 0) {
                vecAns[i--] = k-1;
            }
        }
    }
    else { // low 和 high位数相同时
        bool allLeftIsK_1 = false;
        if (vecHigh[j] == k-1) {
            allLeftIsK_1 = true;
            for (int l = j; l >= 0; l--) {
                if (vecHigh[l] != k-1) {
                    allLeftIsK_1 = false;
                    break;
                }
            }
        }
        if (allLeftIsK_1) // 123456 123999 -> 123999 high 与low的不同位上都是k-1, ans = high
            vecAns = vecHigh;
        else {  // 123456 123567 -> 123499 low 从不同位的下一位开始置k-1
            vecAns = vecLow;
            j--; // 从不同位的下一位置k-1
            while (j >= 0) {
                vecAns[j--] = k-1;
            }
        }
    }
    long ans = 0;
    long power = 1;
    for (int i = 0; i < vecAns.size(); i++) {
        ans += power * vecAns[i];
        power *= k;
    }
    return ans;
}

int main() {
    int q;
    cin >> q;
    long low, high, ans;
    int k; 
    for (int i = 0; i < q; i++) {
        cin >> k >> low >> high;
        ans = query(low, high, k);
        cout << ans << endl;
    }
    return 0;
}

先把 low和high都转换成k进制数,然后寻找在[low, high]之间k进制中k-1最多的数,为方便k=10
 123 123456 -> 099999:二者位数不同时, 把high最高位变成0,后面其他位置为9即可
 123 999999 -> 999999 需要注意high所有位都为9时,ans = high, 玛德这种情况找了好久才找到,sad
 123456 123556 -> 123499 二者位数相同时,把low从位数不同的下一位到最后置为9即可
 123456 123999 -> 123999 需要注意high在不同位往后都为9时, ans = high

发表于 2019-08-09 18:03:05 回复(0)
q = int(input().strip())

# 将十进制转换为k进制,k进制的每一位,用列表中的一个数表示,注意当k 大于10时,k 进制中的每一位可能为两位数
def dec2k(dec):
    ansk = []
    while dec // k:
        ansk.append(dec % k)
        dec = dec // k
    ansk.append(dec)
    ansk = ansk[::-1]
    return ansk

# 将k进制转换为十进制,k进制的每一位,用列表中的一个数表示,注意当k 大于10时,k 进制中的每一位可能为两位数
def k2dec(rans):
    ansd = 0
    tmp = 1
    for i in range(len(rans)-1, -1, -1):
        ansd += rans[i] * tmp
        tmp *= k
    return ansd
# k进制表示中,k-1的数量最多的数,且输出最小的,即k进制数每一位均为k-1构成
def get_ans():
    if len(lvalue) == 0 or len(rvalue) == 0:
        return
    # 第一种全为(k-1), l <= and <= r
    record, tmp = 0, 0
    while tmp <= r:
        record = tmp
        tmp = tmp * k + (k-1)
    # print("record:", record)
    if record >= l:
        return record

    else:
        ''' # 每判断一下都需要进制转换,复杂度太高,超时,由于每次只更新一位,因此,可以直接修改
        for i in range(len(lvalue)-1, -1, -1):
            t = lvalue[i]
            lvalue[i] = k-1
            if k2dec(lvalue) > r:  # 大于,则还原
                lvalue[i] = t
                return k2dec(lvalue)
        '''

        dec = k2dec(lvalue)
        tmp = 1
        for i in range(len(lvalue) - 1, -1, -1):
            dec = dec + (k - 1 - lvalue[i]) * tmp
            tmp = tmp * k
            t = lvalue[i]
            lvalue[i] = k - 1
            if dec > r:  # 大于,则还原
                lvalue[i] = t
                return k2dec(lvalue)

while q > 0:
    k, l, r = map(int, input().strip().split())
    lvalue = dec2k(l) 
    rvalue = dec2k(r) 
    print(get_ans())
    q -= 1

'''
15
4 8442097414683844 8442097414683844
3 3173466882309064 3173466882309073
4 8527527027194177 8527527027194276
4 2661113491247500 2661113491248499
16 4448712248766526 4448712248776525
13 2684426398058983 2684426398158982
14 6562761408288807 6562761409288806
4 2847109288743406 2847109298743405
12 3011167199031338 3011167299031337
7 8655416323525458 8655417323525457
13 177186968879953 177196968879952
2 4133390730537405 4133490730537404
13 4680075382111731 4681075382111730
11 5341708995347620 5351708995347619
8 114951857079067 214951857079066
'''

 您的代码已保存
运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。
case通过率为86.67%

在本地跑,测试用例都通过了,不知道是哪里出现问题,我已经将原有的进制转换优化了,复杂度应该是O(n),难道真的是Python运行太慢了???有大佬麻烦指点一下,谢谢


发表于 2019-08-05 09:48:28 回复(1)
k进制,下限L,上限R,差值d=R-L。
思路是这样的:
先求出上限R的位数b。
if,R等于b位k进制数的最大值(比如5位3进制的22222),那么输出就是R;
else if,L小于b位k进制数的最小值(比如5位3进制的10000),那么输出就是(b-1)位k进制数的最大值(比如4位3进制的2222);
再else,说明L和R的位数一样,用一个长度为b的数组,存储k进制L的各位值。从最低位开始,将各位值改为(k-1),L的增加量就是d的减少量,如果d<=0,说明无法再增大了,输出并终止循环。
用java写的程序如下:
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scn=new Scanner(System.in);
        while(scn.hasNextInt()){
            int q=scn.nextInt();
            for(int t=0;t<q;t++){
                int k=scn.nextInt();
                long l=scn.nextLong();
                long r=scn.nextLong();
                long d=r-l;
                long temp=r;
                int b=1;
                while((temp/=k)!=0) b++;
                if(Math.pow(k,b)-1==r) System.out.println(r);
                else if(Math.pow(k,b-1)>l) System.out.println((long)Math.pow(k,b-1)-1);
                else{
                    temp=l;
                    long[] a=new long[b];
                    for(int j=0;j<b;j++){
                        a[j]=temp%k;
                        temp/=k;
                    }
                    for(int j=0;j<b;j++){
                        d-=(k-1-a[j])*(long)Math.pow(k,j);
                        if(d<=0) System.out.println(l);
                        if(d<=0) break;
                        l=r-d;
                    }
                }
            }
            break;
        }
    }
}
反复考虑过代码应该没问题,pow函数的浮点不确定性也测试过没有影响,但是通过率只有20%(没有超时或内存不足的问题,就是没通过),求教问题出在哪
发表于 2020-06-30 18:41:19 回复(1)
import java.util.ArrayList;
import java.util.Scanner;
/*
 *    低位变 k-1 时,巧妙做法:假如百位数是5(八进制),
 *    那么变成七(八进制数百位)要加 2,对应十进制数要加 2*(8^2)
 */
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for (int i = 0; i < n; i++) {
			int k = sc.nextInt();
			long l = sc.nextLong();
			long r = sc.nextLong();
			System.out.println(count(k, l, r));
		}
	}

	public static long count(int k, long l, long r) {
//		int num = 0;
//		String str_l = invert(l, k);
//		String str_r = invert(r, k);
		
		ArrayList<Long> start = invert(l,k);
		long sum = 1;
		for(int i = 0;i < start.size();i++){
			long ii = k - 1 - start.get(i);
			if(l + ii * sum <= r){
				l = l + ii * sum;
			}else{
				return l;
			}
			sum *= k;
		}
		
		// 当l所有k进制数位全变成k-1时,仍不超过r时
		while(l < r){
//			long iii = k * sum;
			long iii = (k - 1) * sum;
			if(l + iii <= r){
				l += iii;
			}else{
				return l;
			}
			sum *=k;
		}
		// for(int i = 0;i < )
		return l;
	}

	// public static String invert(long x,int k){
	// LinkedList<Long> ll = new LinkedList<>();
	// long r = 0;
	// while(x > 0){
	// r = x % k;
	// ll.addFirst(r);
	// x /= k;
	// }
	// StringBuffer sb = new StringBuffer();
	// for(int i = 0;i < ll.size();i++){
	// sb.append(ll.get(i));
	// }
	// return sb.toString();
	// }
	public static ArrayList<Long> invert(long x, int k) {
		ArrayList<Long> arr = new ArrayList<>();
		long r = 0;
		while(x > 0){
			r = x % k;
			arr.add(r);
			x /= k;
		}
		return arr;
	}
}

发表于 2019-09-02 10:13:49 回复(0)
q = int(input())
from collections import deque
from math import pow
def ToK(num,k):
    res = deque()
    while num:
        res.appendleft(num%k)
        num //= k
    return list(res)
def Tonum(res,k):
    ans = 0
    temp = 1
    for i in range(len(res)-1,-1,-1):
        ans += res[i] *temp
        temp *= k
    return ans
    #ans = 0
    #temp = 0
    #for i in reversed(range(len(res))):
    #    ans += res[i] * pow(k,temp)
    #    temp += 1
    #return int(ans)


for i in range(q):
    k, l, r = tuple(map(int, input().split()))
    record, tmp = 0, 0
    while tmp <= r:
        record = tmp
        tmp = tmp * k + (k - 1)
    if record >= l:
        print(record)
    else:
        low_k = ToK(l,k)
        for i in reversed(range(len(low_k))):
            if low_k[i] == k-1:
                continue
            else:
                change = low_k[i]
                low_k[i] = k-1
                if Tonum(low_k[:],k) > r:
                    low_k[i] = change
                    break
        print(Tonum(low_k[:],k))
很神奇的是用了pow函数居然通不过,很奇怪,希望大神讲解一下就是Tonum注释部分,因为原理是一样的
发表于 2019-08-15 12:40:04 回复(0)
import math
q = int(input())

def func(k, l, r):
    if l == r: return l
    if l == 0: return l
    order = math.ceil(math.log(l, k))

    flag =False # k=10为例:寻找 [l,r] 内是否有 99,999,9999... 如果有,就输出最长的 9999。
    for i in range(order, math.ceil(math.log(r, k)) + 1):
        mid = k ** i - 1
        if mid <= r and mid >= l:
            min_res = mid
            flag = True
    if flag:
        return min_res

    
    # 上一部如果没找到连续的 9 组成的数,那就不看最高位,只看后面几位,如此递归下去:
    # k=10: 【3333,5678】-> 3000 +【333,2678】-> 3000 + 999 = 3999
    else: 
        left_ = k ** (order - 1)
        left = left_ * int(l / left_)
        min_res = left + func(k, l - left, r - left)

    return int(min_res)


for i in range(q):
    k, l, r = [int(x) for x in input().split()]
    print(func(k, l, r))

不需要很复杂吧,还差一步递归最后终止的判断,否则特殊情况死循环

编辑于 2019-08-14 21:18:38 回复(0)
#include<iostream>
#include<vector>
using namespace std;
 
vector<long> trans(long m,long k)  //将数m转化为k进制
{
    long result = m/k;   //商
    long remain = m%k;    //余数
    vector<long> trans_result;  //转化后的结果
    
    while(result!=0)
    {
        trans_result.push_back(remain);
        remain = result%k;
        result = result/k;
    }
    
    trans_result.push_back(remain);
    return trans_result;  //返回二进制的转化结果
}
 
 
 
long cal(vector<long> trans_result,long m)
{
    long num=0;
    for(unsigned int i=0;i<trans_result.size();i++)
    {
        if(trans_result[i]==m)
            num++;
    }
    return num;
}


void add_cal(vector<long>& trans_result,unsigned int& size,long m,long& num)
{
    //计算trans_result+1后的符合要求的数的数量,赋值给num
    //trans_result里面的数+1
    unsigned int i=0;
    unsigned int temp_size=size;
    for(i=0;i<temp_size;i++)  //进位
    {
        if(trans_result[i]==m)
        {
            trans_result[i]=0;
            num -=1; 
            if(i==size-1)
            {
                trans_result.push_back(1);
                size +=1;
            }
        }
        
        else if(trans_result[i]<m)  //尼玛..
        {
            trans_result[i] +=1;
            if(trans_result[i]==m)
                num+=1;
            break;
        }
    }
    



}
 
 
int main()
{
    long q,k;
    long  l,r;

    cin>>q;  //组数 15

    for(int i=0;i<q;i++)     //q组询问
    {
        cin>>k;  //进制
        cin>>l;  //下限
        cin>>r;  //上限
        
        vector<long> trans_ = trans(l,k);   //下限的转化结果 7
        unsigned int size = trans_.size();  //数组大小
        long max_num = cal(trans_,k-1);    //符合要求的最多数量 1
        long max_ = l;               //最佳数 7
        long num = max_num;          //当前数的符合数量 1
        for(long m=l+1;m<=r;m++)    
        {
           add_cal(trans_,size,k-1,num);
           if(num>max_num)
           {
               max_num = num;
               max_ = m;
           }
            
        }
        
        cout<<max_;
    }

}
有没有大神告诉我为啥会超时......没有反复算余数,而是用一个数组存放进制结果,每次在进制结果的基础上加一,一边更新k-1的个数....
发表于 2019-08-08 16:45:56 回复(2)
用java写的话如果用Scanner去读取数据会超时,所以用了BufferedReader去读取数据,成功AC

代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

/**
 * @author YHX
 * @date 2019/8/4 17:25
 * description
 */
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /**
     * call thReader method to initialize reader for InputStream
     */
    static void init(InputStream input) {
        reader = new BufferedReader(
                new InputStreamReader(input));
        tokenizer = new StringTokenizer("");
    }

    /**
     * get next word
     */
    static String next() throws IOException {
        while (!tokenizer.hasMoreTokens()) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                    reader.readLine());
        }
        return tokenizer.nextToken();
    }

    static int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    static long nextLong() throws IOException {
        return Long.parseLong(next());
    }

    static double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        Reader.init(System.in);
        int n = Reader.nextInt();
        while (n-- != 0) {
            int k = Reader.nextInt();
            long l = Reader.nextLong();
            long r = Reader.nextLong();
            int[] llist = dec2K(l, k);
            long temp = 0;
            long[] longs = new long[1000];
            int cnt = 0;
            while (temp <= r) {
                longs[cnt] = temp;
                temp = temp * k + k - 1;
                cnt++;
            }
            if (longs[cnt - 1] >= l) System.out.println(longs[cnt - 1]);
            else {
                for (int i = 0; i < llist.length; i++) {
                    int tm = llist[i];
                    llist[i] = k - 1;
                    long x = K2Dec(llist, k);
                    if (x > r) {
                        llist[i] = tm;
                        System.out.println(K2Dec(llist, k));
                        break;
                    }
                }
//                System.out.println(ans);
            }
        }
    }

    private static long K2Dec(int[] list, int k) {
        long sum = 0;
        for (int i = list.length - 1; i >= 0; i--) {
            sum = sum * k + list[i];
        }
        return sum;
    }

    private static int[] dec2K(long m, int k) {
        int cnt = 0;
        long mm = m;
        while (mm != 0) {
            mm /= k;
            cnt++;
        }
        int[] list = new int[cnt];
        int j = 0;
        while (m != 0) {
            list[j++] = (int) (m % k);
            m /= k;
        }
//        System.out.println(Arrays.toString(list));
        return list;
    }
}
/*
1000
11 995685164714609 995685164714759
12 2736421049381634 2736421049406512
14 9118803148252731 9118865035350336
2 1999825671666783 2000343892027004
14 7193328445426973 7193328445427058
11 7732658659093208 7732658659093623
9 1480868347971885 1480868506943790
14 3042539992504302 3042540322182591
8 1389231659305990 1399565743027217
14 2932108313570593 7566855981538408
12 7325933386074263 7325933386150179
15 1475130408804666 1475130408814717
4 8369091548439239 8369091832832186
2 584922365242306 584928003053033
11 7722607142326413 7793990995548130
4 6402524556803908 6495021063230295
3 3030210225507683 3030210225507723
13 9258166811155326 9258166811155824
15 9721331831836073 9721331831863924
6 2729140398142086 2729140398194424
13 8051442428579126 8051442520463831
10 7797474285534101 7797474382623448
11 8086464978132222 8086507915606045
6 9943020962485391 9943028723407452
15 5136403641668815 5137054586129716
11 5622258309274901 5622404426526100
8 1536295471800580 2248394876465846
 */

/*
15
4 8442097414683844 8442097414683844
3 3173466882309064 3173466882309073
4 8527527027194177 8527527027194276
4 2661113491247500 2661113491248499
16 4448712248766526 4448712248776525
13 2684426398058983 2684426398158982
14 6562761408288807 6562761409288806
4 2847109288743406 2847109298743405
12 3011167199031338 3011167299031337
7 8655416323525458 8655417323525457
13 177186968879953 177196968879952
2 4133390730537405 4133490730537404
13 4680075382111731 4681075382111730
11 5341708995347620 5351708995347619
8 114951857079067 214951857079066
 */

发表于 2019-08-05 14:48:19 回复(0)
#include<iostream>
#include<vector>
#include<algorithm>
  
using namespace std;
typedef long long LL;
/*
十进制查询范围1,100
对应八进制表达64 100
八进制表达的搜索范围100 144
7 77 777
*/
  
//将10进制数转为K进制数
void toKPrime(LL n,vector<int>& KPrime,int K)
{
    while(n){
        KPrime.push_back(n%K);
        n/=K;
    }
    reverse(KPrime.begin(),KPrime.end());
}
//将k进制表达的数字转为10进制
LL toDecimal(vector<int> &KPrime,int K)
{
    LL ans=0;
    vector<int>::iterator it;
    for(it=KPrime.begin();it!=KPrime.end();it++)
    {
        ans=ans*K+*it;
    }
    return ans;
}
  
void print(vector<int>& arr){
    vector<int>::iterator it;
    for(it=arr.begin();it!=arr.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}
  
void print(vector<LL>& arr){
    vector<LL>::iterator it;
    for(it=arr.begin();it!=arr.end();it++)
    {
        cout<<*it<<" ";
    }
    cout<<endl;
}
  
int main(){
    int k;
    LL l,r;
    int q;
    cin>>q;
    while(q>0){
        cin>>k>>l>>r;
        LL tmp=0;
        vector<LL> record;
        while(tmp<=r){
            record.push_back(tmp);
            tmp=tmp*k+k-1;
        }
        //print(record);
        if(record.at(record.size()-1)>=l)
        {
            cout<<record.at(record.size()-1)<<endl;
        }
        else
        {
            vector<int> LK,RK;
            toKPrime(l,LK,k);
            //print(LK);
            toKPrime(r,RK,k);
            //print(RK);
            LL ans=l;
            vector<int>::iterator it;
            for(it=LK.end()-1;it>=LK.begin();it--)  //从低位将数字改成7直到大于r为止
            {
                int tmp=*it;
                *it=k-1;
                if(toDecimal(LK,k)>r)
                {
                    *it=tmp;
                    cout<<toDecimal(LK,k)<<endl;
                    break;
                }
                else
                {
                    ans=toDecimal(LK,k);
                }
            }
        }
        q--;
    }
    return 0;
}

编辑于 2019-08-02 21:01:50 回复(0)

代码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> rdec2k(long long dec, int k) {
    vector<int> ans;
    while (dec / k) {
        ans.push_back(dec % k);
        dec = dec / k;
    }
    ans.push_back(dec);
    return ans;
}
void get_ans(vector<int> &vrans, vector<int> &vrl, vector<int> &vrr, int k) {
    if (vrl.empty() || vrr.empty()) {
        return;
    }
    if (vrl.size() < vrr.size()) {
        vrans.assign(vrr.size() - 1, k - 1);
    }
    else { // vrl.size() < vrr.size()
        if (vrr.back() > vrl.back()) {
            vrans.assign(vrl.size() - 1, k - 1);
            vrans.push_back(vrl.back());
            //return;
        }
        else {// vrr.back() == vrl.back()
            int tmp = vrl.back();
            vrl.pop_back();
            vrr.pop_back();
            get_ans(vrans, vrl, vrr, k);
            vrans.push_back(tmp);
        }
    }
}
long long k2dec(vector<int> vrans, int k) {
    long long ans = 0;
    long long tmp = 1;
    for (int i = 0; i < vrans.size(); ++i) {
        ans += vrans[i] * tmp;
        tmp *= k;
    }
    return ans;
}
int main() {
    int N;
    while (cin >> N) {
        while (N--) {
            int k;
            long long l, r;
            cin >> k >> l >> r;
            vector<int> vrl = rdec2k(l, k); // 逆序存放k进制的l
            vector<int> vrr = rdec2k(r + 1, k); // 逆序存放k进制的r+1, 数可以取的范围是[l, r+1)
            vector<int> vrans; // 逆序存放k进制的答案
            get_ans(vrans, vrl, vrr, k);
            cout << k2dec(vrans, k) << endl; // 将答案转化成10进制后输出
        }
    }
    return 0;
}

以上是代码

编辑于 2019-07-31 12:30:22 回复(0)