UVA1594 Ducci Sequence 解题报告
题目链接
https://vjudge.net/problem/UVA-1594
题目大意
对于一个n元组(a1, a2, …, an),可以对于每个数求出它和下一个数的差的绝对值,得到一个新的n元组(|a1-a2|, |a2-a3|, …, |an-a1|)。重复这个过程,得到的序列称为Ducci序列,例如:(8, 11, 2, 7) -> (3, 9, 5, 1) -> (6, 4, 4, 2) -> (2, 0, 2, 4) -> (2, 2, 2, 2) -> (0, 0, 0, 0).也有的Ducci序列最终会循环。输入n元组(3≤n≤15),你的任务是判断它最终会变成0还是会循环。输入保证最多1000步就会变成0或者循环。
解题思路
序列用vector进行存储,按照题意进行模拟即可,至于判断序列是否重复出现,用set,set<vector< int >>,即可做到对vector进行判重。至于判断每次的序列是否为全0,用朴素的O(n)的循环遍历来判断肯定会超时,我们可以选择在模拟序列过程之前,先预设一个n个0的vector,然后每次就可以直接用==比较运算符来判断当前序列是否变成全0序列了。
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
#define endl '\n';
const int maxn = 1e3 + 10;
const int INF = 0x3fffffff;
const int mod = 1e9 + 7;
int readint() {
int x;
cin >> x;
return x;
}
void solve() {
int n;
cin >> n;
vector<int> seq, zeroSeq;
set<vector<int>> Set;
for (int i = 0; i < n; i++) { // 0序列
zeroSeq.push_back(0);
}
for (int i = 0; i < n; i++) {
seq.push_back(readint());
}
while (true) {
if (seq == zeroSeq) {
cout << "ZERO\n";
break;
}
int a0 = seq[0];
for (int i = 0; i < n; i++) {
if (i == n - 1)
seq[i] = abs(seq[i] - a0);
else
seq[i] = abs(seq[i] - seq[i + 1]);
}
if (Set.count(seq)) {
cout << "LOOP\n";
break;
}
Set.insert(seq);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout << fixed;
cout.precision(18);
solve();
return 0;
}