AT_arc149_a 题解

洛谷链接&Atcoder 链接

本篇题解为此题较简单做法较少码量,并且码风优良,请放心阅读。

1|0题目简述

求满足以下条件的小于 10n 数最大是多少?

  • 每一位数字均相同;

  • m 的倍数。

数据范围:1n1051m109

2|0思路

首先每位数字都相同很好满足,仅需枚举 n 位后,枚举每位的数字 19,注意不包含 0,因为最高位不能0

接着想要满足是 m 的倍数,可以想到类似动态转移的思路,定义二维数组 mp[i][j] 表示在有 i 位数的情况下每位都为 j 的数除以 M余数。在枚举中实时更新答案,因为位数是从 1N,每位是从 19,所以存储的答案一定为最大的解

3|0代码实现

经过以上分析及一些数组设计,很容易即可得到代码。首先我们先看一下 mp 数组的处理

for(int i = 1; i <= n; i ++) for(int j = 1; j <= 9; j ++) { mp[i][j] = (mp[i - 1][j] * 10 + j) % m; if(!mp[i][j]) ans1 = i, ans2 = j; }

可以看到第三行对于 mp 数组状态的转移

mpi,jmpi1,j

可以从 i1 位都是 j 的余数转移过来,根据同余的相关知识很容易推出转移方程式

mpi,j(mpi1,j×10+j)%M

解决状态转移后需更新答案,这一部分很简单就不在赘述。接着需要在处理 mp 数组后,特判 1 的情况:

if(!ans1 || !ans2) { cout << "-1\n"; return 0; }

这样整体代码框架就完成了。

4|0AC code

#include<iostream> using namespace std; long long n, m, mp[100005][15]; long long ans1, ans2; int main() { cin >> n >> m; for(int i = 1; i <= n; i ++) for(int j = 1; j <= 9; j ++) { mp[i][j] = (mp[i - 1][j] * 10 + j) % m; if(!mp[i][j]) ans1 = i, ans2 = j; } if(!ans1 || !ans2) { cout << "-1\n"; return 0; } for(int i = 1; i <= ans1; i ++) cout << ans2; return 0; }

提交记录

The End!


__EOF__

本文作者So_noSlack
本文链接https://www.cnblogs.com/So-noSlack/p/17582278.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   So_noSlack  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示