【刘汝佳书】习题5-2 UVA1594(set判重,vector排序)

【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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值