zoukankan      html  css  js  c++  java
  • Ducci Sequence 解题心得

    原题贴上

    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$displaystyle 
ightarrow$ (| 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) $displaystyle 
ightarrow$ (3, 9, 5, 1) $displaystyle 
ightarrow$ (6, 4, 4, 2) $displaystyle 
ightarrow$ (2, 0, 2, 4) $displaystyle 
ightarrow$ (2, 2, 2, 2) $displaystyle 
ightarrow$ (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) $displaystyle 
ightarrow$ (2, 2, 2, 2, 4) $displaystyle 
ightarrow$ ( 0, 0, 0, 2, 2$displaystyle 
ightarrow$ (0, 0, 2, 0, 2) $displaystyle 
ightarrow$ (0, 2, 2, 2, 2) $displaystyle 
ightarrow$ (2, 0, 0, 0, 2) $displaystyle 
ightarrow$

     

     

    (2, 0, 0, 2, 0) $displaystyle 
ightarrow$ (2, 0, 2, 2, 2) $displaystyle 
ightarrow$ (2, 2, 0, 0, 0) $displaystyle 
ightarrow$ (0, 2, 0, 0, 2) $displaystyle 
ightarrow$ (2, 2, 0, 2, 2) $displaystyle 
ightarrow$ (0, 2, 2, 0, 0) $displaystyle 
ightarrow$

     

     

    (2, 0, 2, 0, 0) $displaystyle 
ightarrow$ (2, 2, 2, 0, 2) $displaystyle 
ightarrow$ (0, 0, 2, 2, 0) $displaystyle 
ightarrow$ (0, 2, 0, 2, 0) $displaystyle 
ightarrow$ (2, 2, 2, 2, 0) $displaystyle 
ightarrow$ ( 0, 0, 0, 2, 2$displaystyle 
ightarrow$ ...

     

    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$ le$n$ le$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 }

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



  • 相关阅读:
    yii2.0 邮件发送如何配置
    php(ThinkPHP)实现微信小程序的登录过程
    微信小程序开发
    一个中高级PHP工程师所应该具备的能力
    如何解决PHP的高并发和大流量的问题
    对于PHP面试知识点的小结
    Centos7 redis设置开机自启动
    CENTOS7下REDIS设置密码、开放远程访问权限
    CentOS7安装Redis
    SQL Server 2012允许远程连接(Windows Server 2016)
  • 原文地址:https://www.cnblogs.com/shawn-ji/p/4647610.html
Copyright © 2011-2022 走看看