URAL1095 Nikifor 3

题目传送门

打表找规律。

首先你得先打个表,就像这样:

1
2
3
4
5
6
int a[] = { 1,2,3,4 };
do {
int x = 0;
rep(i, 4) cout << a[i], x = x * 10 + a[i];
cout << ' ' << x % 7 << endl;
} while (next_permutation(a, a + 4));

然后你就能惊讶地发现,对于每个 $i\in [1,7]$,都有至少一个 $1,2,3,4$ 的排列满足:$(组成的四位数)\equiv i\pmod i$。

所以考虑先在字符串中去掉 $1,2,3,4$,将剩余的所有数字放在最后面,并处理出这串数 $\bmod 7$ 是多少,然后把 $1,2,3,4$ 按照某种顺序放在最前面就行了。

之所以要把剩余部分放在最后面而不是最前面的原因是,如果有这样一组数据:001234,就会出现前导零。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int T_, case_;
int A[7][4], sum, p;
string s, t;
bool f[5];
void solve() {
sum = 0;
init(f, 0);
cin >> s;
t = "";
p = 1;
rep(i, s.size()) {
int x = s[i] - '0';
if (x >= 1 && x <= 4 && !f[x])f[x] = 1;
else {
t += s[i];
p = p * 10 % 7;
sum = (sum * 10 + x) % 7;
}
}
rep(i, 7)if ((i * p + sum) % 7 == 0) {
rep(j, 4)cout << A[i][j];
cout << t << endl;
}
}
int main() {
init(A, -1);
int a[] = { 1,2,3,4 };
do {
int x = 0;
rep(i, 4) x = x * 10 + a[i];
if (A[x % 7][0] == -1)rep(i, 4)A[x % 7][i] = a[i];
} while (next_permutation(a, a + 4));
T_ = 1;
cin >> T_;
for (case_ = 1; case_ <= T_; case_++)solve();
return 0;
}
作者

Rushroom

发布于

2023-01-06

更新于

2023-03-16

许可协议

CC BY-NC-SA 4.0

评论