惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
D
Docker
H
Help Net Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
C
Check Point Blog
S
SegmentFault 最新的问题
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
M
MIT News - Artificial intelligence
B
Blog RSS Feed
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
美团技术团队
I
InfoQ
Blog — PlanetScale
Blog — PlanetScale

OhYee 博客

小鹏辅助驾驶测评|OhYee 博客 小鹏非支持手机开启自动解锁|OhYee 博客 使用函数计算实现 301 重定向|OhYee 博客 针对 HTML 内容使用 Ant Design 图片弹框|OhYee 博客 博客进程泄露及僵尸进程解决|OhYee 博客 蓝易云服务器体验|OhYee 博客 SSH 调起本地 VSCode|OhYee 博客 【2022 秋招内推】阿里云后端研发工程师|OhYee 博客 使用函数计算获取 IP 地址信息|OhYee 博客 正确获取客户端 IP/HTTP Header 也可能重复|OhYee 博客 评测 Oculus Quest2 及 BigScreen|OhYee 博客 NextJS 热重载保留状态|OhYee 博客 如何优雅地贴 gist 代码|OhYee 博客 Linux 精细化文件权限|OhYee 博客 VSCode 容器开发环境|OhYee 博客 Clash 的不兼容更新排查|OhYee 博客 Zeek 导出 PCAP|OhYee 博客 记一次 ssh 配置问题|OhYee 博客 Git Commit 规范化工具|OhYee 博客 谈谈《星之卡比-探索发现》|OhYee 博客 VSCode 快捷键绑定 Shell 命令|OhYee 博客 ASN.1 语法及 X.509 证书格式解析解析|OhYee 博客 腾讯企业邮箱忽略 MX 记录发信|OhYee 博客 Chrome/Edge 标签组插件|OhYee 博客 【应届内推】阿里云后端研发工程师|OhYee 博客 损坏的 Typecho 备份处理为 JSON|OhYee 博客 VS Code VIM 插件高效使用|OhYee 博客 SSH 正反向代理|OhYee 博客 Let's Encrypt 根证书过期引发的问题|OhYee 博客 OpenWRT 忽略内核依赖|OhYee 博客
HDU 5936.Difference(2016 CCPC 杭州 D)|OhYee 博客
2016-11-21 · via OhYee 博客

题目

Description

Little Ruins is playing a number game, first he chooses two positive integers y and K and calculates f(y,K), here

f(y,K) = ∑in every digits of y zK (f(233,2) = 22+32+32=22)

then he gets the result

x=f(y,K)-y

As Ruins is forgetful, a few seconds later, he only remembers K, x and forgets y. please help him find how many y satisfy x=f(y,K)-y.

Input

First line contains an integer T, which indicates the number of test cases.

Every test case contains one line with two integers x, K.

Limits
1≤T≤100
0≤x≤109
1≤K≤9

Output

For every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the result.

Sample Input

2
2 2
3 2

Sample Output

Case #1: 1
Case #2: 2

题解

求所有满足 x=f(y,K)-y 的数量
计算一下,可以发现 y 最多为 10 位 (计算下极端情况)
而暴力搜索 10 位的数字显然会超时
可以采用 中途相遇法 的思路,将 10 位数字分成两个 5 位
然后分别计算两部分,再对两部分进行比较即可

首先可以知道, f(y,K) 函数是一个有确定的函数,因此可以打表直接查询结果
而每次需要求的 zK 也是有确切结果的,也可以打表(对于这道题,不打表时间会多很多)

x=f(y,K)-y 化成 x=f(a,K)+f(b,K)-a*100000-b 其中 a b 分别是 y 的前 5 位和后 5 位
可以看出, f(a,K)-a*100000f(b,K)-b 可以分别在自己的循环里计算

用一个数组来记录第一个循环能得到的结果,在第二个循环里累计其结果在第一个循环里的数量
(用 map 会超时,可以用 lower_bound()upper_bound() 快速求个数)

特别注意,如果 x=0 在两个循环会被重复计算 1 次,因此要额外 -1

代码量不大,思路也比较容易理解,注意各种打表优化即可

代码

//#include <ctime>
//#define debug

#include <cstdio>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

typedef long long LL;

LL List[100005][10];
LL Pre[100005];
int pw[10][10];

int Pow(int a,int n) {
    if(pw[a][n] == -1){
        if(n == 1) pw[a][n] = a;
        else if(n == 0) pw[a][n] = 1;
        else pw[a][n] = Pow(a,n / 2) * Pow(a,n - n / 2);
    }
    return pw[a][n];
}

inline LL f(LL y,int k) {
    // if(List[y][k] == -1) {
    //     LL sum = 0;
    //     while(y) {
    //         sum += Pow((int)(y % 10),k);
    //         y /= 10;
    //     }
    //     List[y][k] = sum;
    // }
    return List[y][k];
}

int lower_bound(LL *arr,int size, LL key) {
    int half;
    int mid;
    int first = 0;
    while (size > 0) {
        half = size >> 1;
        mid = first + half;
        if (arr[mid] < key) {
            first = mid + 1;
            size = size - half - 1;
        } else {
            size = half;
        }
    }
    return first;
}
int upper_bound(LL *arr,int size, LL key) {
    int mid;
    int first = 0;
    int half;
    while (size > 0) {
        half = size >> 1;
        mid = half + first;
        if (arr[mid] > key) {
            size = half;
        } else {
            first = mid + 1;
            size = size - half - 1;
        }
    }
    return first;
}

inline int Count(LL pre) {
    return upper_bound(Pre,100000,pre) - lower_bound(Pre,100000,pre);
}

int main() {
    #ifdef debug
    freopen("in.txt","r",stdin);
    int start = clock();
    #endif

    cin.tie(0);
    cin.sync_with_stdio(false);

    int T;
    cin >> T;
    //scanf("%d",&T);

    memset(pw,-1,sizeof(pw));

    for(int i=0;i<100000;i++){
        for(int j=1;j<=9;j++){
            LL sum = 0;
            int y = i;
            while(y) {
                sum += Pow((int)(y % 10),j);
                y /= 10;
            }
            List[i][j] = sum;
        }
    }
    //memset(List,-1,sizeof(List));

    for(int kase = 1;kase <= T;kase++) {
        LL x;
        int k;
        cin >> x >> k;
        //scanf("%d%d",&x,&k);

        //前5位的各位k次方 - 前五位数据
        for(int i = 0;i < 100000;i++) {
            LL pre = f(i,k) - (LL)i * 100000;
            Pre[i] = pre;
        }
        
        sort(Pre,Pre + 100000);
        LL cnt = 0;

        //后5位的各位k次方 - 后五位数据
        for(int i = 0;i < 100000;i++) {
            LL post = f(i,k) - (LL)i;
            LL pre = x - post;
            cnt += Count(pre);
        }
        cout << "Case #" << kase << ": " << cnt-(x==0) << endl;
       // printf("Case #%d: %d\n",kase,cnt);
    }

    #ifdef debug
    printf("Time:%.3lfs\n",double(clock() - start) / CLOCKS_PER_SEC);
    #endif

    return 0;
}