【2019.4.7】把Ducci序列看成Gucci序列了……
本题结构清晰,但对于数据结构的选取需要有思考。
数据结构的选取思路:
本题数据的基本单位为n元组,对其进行的操作有:① 初始化,② 赋值/更改值,③ 判重(其实也就是比较)
可选的存储方式基本有两种:
1、数组:
① 初始化时要么malloc,要么开一个比较大的数组;
② 赋值操作比较简单,直接用下标就可以访问、更改数值;
③ 对于判重,首先想到的是set
,但用数组作为set的元素,感觉很复杂的样子;如果不用set,那就要把所有n元组存起来,挨个比较,也很复杂的样子
2、vector
① 不用担心初始化的问题,来一个元素就push_back一个
② 赋值操作稍显复杂,需要用iterator
才能改变vector中元素的值
③ 判重问题非常简单,直接用set
即可,对于vector已经定义好了“<”、“==”等比较运算符,不需我们费心
综上所述,感觉vector更加适合存储n元组。
最终定义的数据结构如下:
1、set<vector<int>> s;
用于存储n元组的集合,每当生成一个新的n元组v
,用s.count(v)
就可以判断新n元组是否重复。
2、vector<int> vzero;
用于存储全0的n元组,每当生成一个新的n元组v
,用v == vzero
就可以判断新n元组是不是全0.
3、vector<int> vcur;
用于存储当前的n元组,初值为输入的n元组,之后不断迭代生成下一个n元组。迭代生成的过程:
//生成下一序列
int x1 = vcur[0];
for(it=vcur.begin(); it!=vcur.end()-1; it++)
(*it) = abs((*it) - (*(it+1))); //前n-1个元素
(*it) = abs((*it) - x1); //第n个元素
思路:
1、输入初始n元组,把元素push_back到vcur
中,并把vcur
存入集合s
中
2、while循环,
① 每循环一次,更新vcur
的值为下一个n元组的值
② 然后判断vcur
是否重复,是否等于vzero
③ 如果是则输出结果、退出循环;如果不是则存入集合s
中,继续循环
代码:
#include <iostream>
#include <vector>
#include <set>
using namespace std;
set<vector<int>> s;
vector<int> vzero;
vector<int> vcur;
int main()
{
//freopen("C:\\Users\\Summer\\Desktop\\input.txt", "r", stdin);
//freopen("C:\\Users\\Summer\\Desktop\\output.txt", "w", stdout);
int T;
cin>>T;
int n;
int x;
while(T--) {
//多测例,初始化
s.clear();
vzero.clear();
vcur.clear();
//输入
cin>>n;
for(int i=0; i<n; i++) {
cin>>x;
vcur.push_back(x);
vzero.push_back(0);
}
//生成序列并判断
s.insert(vcur); //将初始序列插入set
vector<int>::iterator it; //遍历当前序列,生成下一序列
while(true) {
//生成下一序列
int x1 = vcur[0];
for(it=vcur.begin(); it!=vcur.end()-1; it++)
(*it) = abs((*it) - (*(it+1))); //前n-1个元素
(*it) = abs((*it) - x1); //第n个元素
//判断是否为0
if(vcur == vzero) {
cout<<"ZERO"<<endl;
break;
}
//判断是否重复
else if(s.count(vcur)) {
cout<<"LOOP"<<endl;
break;
}
//既不为0,也不重复,就加入集合,继续生成下一序列
else {
s.insert(vcur);
}
}
}
return 0;
}