首页 > 其他 > 详细

Ducci Sequence 解题心得

时间:2015-07-15 11:00:15      阅读:176      评论:0      收藏:0      [点我收藏+]

原题贴上

A Ducci sequence is a sequence of n-tuples of integers. Given an n-tuple of integers (a1a2, ... an), the next n-tuple in the sequence is formed by taking the absolute differences of neighboring integers:

 

 

a1a2... an技术分享 (| a1 - a2|,| a2 - a3|, ... ,| an - a1|)

 

Ducci sequences either reach a tuple of zeros or fall into a periodic loop. For example, the 4-tuple sequence starting with 8,11,2,7 takes 5 steps to reach the zeros tuple:

 

 

(8, 11, 2, 7) 技术分享 (3, 9, 5, 1) 技术分享 (6, 4, 4, 2) 技术分享 (2, 0, 2, 4) 技术分享 (2, 2, 2, 2) 技术分享 (0, 0, 0, 0).

 

The 5-tuple sequence starting with 4,2,0,2,0 enters a loop after 2 steps:

 

 

(4, 2, 0, 2, 0) 技术分享 (2, 2, 2, 2, 4) 技术分享 ( 0, 0, 0, 2, 2技术分享 (0, 0, 2, 0, 2) 技术分享 (0, 2, 2, 2, 2) 技术分享 (2, 0, 0, 0, 2) 技术分享

 

 

(2, 0, 0, 2, 0) 技术分享 (2, 0, 2, 2, 2) 技术分享 (2, 2, 0, 0, 0) 技术分享 (0, 2, 0, 0, 2) 技术分享 (2, 2, 0, 2, 2) 技术分享 (0, 2, 2, 0, 0) 技术分享

 

 

(2, 0, 2, 0, 0) 技术分享 (2, 2, 2, 0, 2) 技术分享 (0, 0, 2, 2, 0) 技术分享 (0, 2, 0, 2, 0) 技术分享 (2, 2, 2, 2, 0) 技术分享 ( 0, 0, 0, 2, 2技术分享 ...

 

Given an n-tuple of integers, write a program to decide if the sequence is reaching to a zeros tuple or a periodic loop.

 

Input 

Your program is to read the input from standard input. The input consists of T test cases. The number of test casesT is given in the first line of the input. Each test case starts with a line containing an integer n(3技术分享n技术分享15), which represents the size of a tuple in the Ducci sequences. In the following line, n integers are given which represents the n-tuple of integers. The range of integers are from 0 to 1,000. You may assume that the maximum number of steps of a Ducci sequence reaching zeros tuple or making a loop does not exceed 1,000.

 

Output 

Your program is to write to standard output. Print exactly one line for each test case. Print `LOOP‘ if the Ducci sequence falls into a periodic loop, print `ZERO‘ if the Ducci sequence reaches to a zeros tuple.

The following shows sample input and output for four test cases.

 

Sample Input 

 

4 
4 
8 11 2 7 
5 
4 2 0 2 0 
7 
0 0 0 0 0 0 0 
6 
1 2 3 1 2 3

 

Sample Output 

 

ZERO 
LOOP 
ZERO 
LOOP


分析:
  题目让我们求循环出现的时候和全0出现的时候, 其实,全0出现后紧接着就会出现循环,所以我们只需专注于找到循环出现。
这里的循环也就是数字的排列出现重复,也就是发现重复即找到。
想到去重,第一个想到的便是STL中的set可以直接保证每个键是唯一的,然而这里这并不能将重复出现的时候标记出来,达不到解题。接着就很自然的想到“标记法”,即——将每种情形和一个bool值对应,出现过记为true,没出现过记为false。每次新出现一个情形先判断对应的bool值,然后就可以判断重复没有啦。
一种情形与一个值对应,最近正在学STL,然后立马就想到了map。
map<A,B> 应题目要求,A为一个有序对比较适合,所以可以用一个结构体将多个数字组成一个整体,B就很自然的使用bool类型。
可是还有一个问题,map<A,B> 里面的A必须要是定义了<操作符的,因为map判断A的唯一性必须要通过<符号比较,具体的判别机制是(a<b,b<a 有且仅有一个成立 ->a b不相等 //否则a b相等),这就需要我们重载A里的<操作符。
按照判别机制,我如下重载
1     bool operator <(const gro &b) const {
2         for (int i = 0; i < n; i++){
3             if (g[i] != b.g[i]) return g[i]<b.g[i];
4         }
5         return false;
6     }

有了这个认识,然后就可以写代码了,如下:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<map>
 4 #include<stdio.h>
 5 using namespace std;
 6 const int N = 16;
 7 bool isloop = 0;
 8 
 9 
10 struct gro
11 {
12     int g[N];
13     int n;
14     void read ()
15     {
16         for (int i = 0; i < n; i++)
17         {
18             cin >> g[i];
19         }
20     }
21     bool iszero(){
22         for (int i = 0; i < n; i++){
23             if (g[i] != 0){
24                 return false;
25             }
26         }
27         return true;
28     }
29 
30     bool operator <(const gro &b) const {
31         for (int i = 0; i < n; i++){
32             if (g[i] != b.g[i]) return g[i]<b.g[i];
33         }
34         return false;
35     }
36 
37     void change()
38     {
39         int temp = g[0];
40         for (int i = 0; i < n - 1; i++)
41         {
42             g[i] = abs(g[i] - g[i + 1]);
43         }
44         g[n - 1] = abs(temp - g[n - 1]);
45     }
46 
47 } g1;
48 
49 
50 
51 
52 
53 map <gro, bool> group;
54 
55 int main()
56 {
57     int T;
58     cin >> T;
59     while (T--){
60         cin >> g1.n;
61         g1.read();
62         group.clear();    // 因为有多组数据,记得要清空!!!
63 group[g1] = true; 64 for (int k = 0; k < 1000; k++){ 65 g1.change(); 66 if (group[g1] == true){ 67 isloop = true; 68 break; 69 } 70 group[g1] = true; //一定要记得!!! 71 } 72 if (g1.iszero() == true){ 73 puts("ZERO"); 74 } 75 else { 76 puts("LOOP"); 77 } 78 bool isloop = false; 79 } 80 81 return 0; 82 }

骚年,加油奋斗吧,毕竟水题。



Ducci Sequence 解题心得

原文:http://www.cnblogs.com/shawn-ji/p/4647610.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!