AtCoder Beginner Contest 181 D 题,https://atcoder.jp/contests/abc181/tasks/abc181_d。
Given is a digit sequence S consisting of the digits from 1
through 9
.
Takahashi, the bee, loves multiples of 8. He is trying to make a multiple of 8 by permuting the digit sequence S.
Determine whether it is possible.
Input is given from Standard Input in the following format:
S
If it is possible to make a multiple of 8 by permuting the digit sequence S, print Yes
; otherwise, print No
.
1234
Yes
For example, permuting 1234 into 1432 results in a multiple of 8.
1333
No
There is no way to permute 1333 into a multiple of 8.
8
Yes
1
through 9
.给一个有数字 1 到 9 构成的字符串,判断能否通过交换位置,使得这个字符串对应的数字可以被 8 整除。
看到这个题目,第一反应是全排序,也就是根据提供的字符串列出全排列,然后再验证是否能被 8 整除。例如字符串为 1234,我们可以通过 STL 的 next_permutation() 函数实现。这样我们写道 1432 的时候,这个数字可以被 8 整除。
但是看到数据长度 2×10^5 的时候,就知道这个方法是不可行的。
仔细思考后,又是一个数学题。这题的核心数学是如何判断一个数字能被 8 整除。
通过数学归纳法,我们可以发现。由于本题没有数字 0。
这样我们就找到了规律。
本题就是统计是否有这样的规律,而不需要去构造字符串。如何使用这样规律呢?
数据长度为 1 和 2,只需要特判就可以了。
数据长度超过 2 的,将对应的字符串每位数字的个数统计出来。使用如下的伪码:
for (int i=104; i<1000; i++) {
统计数字 i 变为有几个 1 ~ 9 构成。将结果保存在数组 tmp[10] 中
比对 tmp 和 num 数组
只要 tmp 数组中的任意一个数据大于 num 数组,说明不能构成
tmp 数组中所有数据都小于等于 num 数组,说明可以构成
}
例如我们输入 98433333333333333333333333333333333333333666666。我们统计每个数字出现的个数,即统计数字 1 ~ 9 出现的个数。这样我们可以得到下面的数组:
num[0]=0;
num[1]=0;
num[2]=0;
num[3]=38;
num[4]=1;
num[5]=0;
num[6]=6;
num[7]=0;
num[8]=1;
num[9]=1;
然后判断这些数字能否组合成为 104、112、...、984、992 这样的数字。当我们遍历到 336 的时候,也就是说末尾三个数字变成 336,就可以被 8 整除。
例如我们输入 1333。我们统计每个数字出现的个数,即统计数字 1 ~ 9 出现的个数。这样我们可以得到下面的数组:
num[0]=0;
num[1]=1;
num[2]=0;
num[3]=3;
num[4]=0;
num[5]=0;
num[6]=0;
num[7]=0;
num[8]=0;
num[9]=0;
然后判断这些数字能否组合成为 104、112、...、984、992 这样的数字。整个遍历完成后,发现没有办法构成被 8 整除的数据。
例如 104 对应的统计数据如下:
num[0]=1;
num[1]=1;
num[2]=0;
num[3]=0;
num[4]=1;
num[5]=0;
num[6]=0;
num[7]=0;
num[8]=0;
num[9]=0;
其中 tmp[0]>num[0],说明没法构成 104。其他数据以此类推。
//https://atcoder.jp/contests/abc181/tasks/abc181_d
//D - Hachi
#include
using namespace std;
string str;//保存字符串
int num[10];//数字0~9
bool judge(int x) {
int t=x;
int tmp[10]={};
while (t) {
tmp[t%10]++;
t/=10;
}
for (int i=0; i<10; i++) {
if (tmp[i]>num[i]) {
return false;
}
}
return true;
}
int main() {
cin>>str;
int len=str.length();
for (int i=0; i
应该是 O(N),有点不是很确定。惭愧。