Ducci Sequence UVA - 1594

本文解析了UVA-1594题的Ducci序列问题,介绍了一个n元组通过特定运算形成的新序列,并讨论了如何判断序列最终是否会归零或者循环。采用C++实现并通过map存储状态进行判重。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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-15),你的任务是判断它最终会变成0还是会循环。

思路:因为涉及到判重的问题,于是用map来保持之前的状态,由于n范围(3-15),于是用map<string,int>来保存一起的状态。

#include <iostream>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;

int number[16],n;
char num[10000];

string transmit(){
    string s;
    for(int j = 1;j<=n;j++){
        int tot=0;
        int x = number[j]; //x为当前n元组的一个数,其位数不确定
        if(x==0) num[++tot] = '0';
        while (x!=0) {
            num[++tot] = x%10 + '0';
            x/=10;
        }
        for(int i = tot;i>=1;i--) s = s + num[i];
    }
    return s;
}
int main(){
    int T;
    cin>>T;
    while(T--){
        map<string,int> dict;
        int zero=1;
        string s;
        cin>>n;
        for(int i = 1;i<=n;i++){
            cin>>number[i];
            if(number[i]) zero = 0; //判断序列是否为0
        }
        if(zero){
            printf("ZERO\n");
            continue;
        }
        s = transmit(); //将序列转换为字符串
        if(!dict.count(s)) dict[s]=0;
        int yes = 1;
        for(int i=1;i<=1000;i++){
            zero = 1;
            int before = number[1];
            for(int j = 1;j<=n;j++){
                if(j!=n) number[j] = int(fabs(number[j]-number[j+1]));
                else number[j] = int(fabs(number[j]-before));
                
                if(number[j]) zero = 0;//判断序列是否为0
            }
            if(zero){
                printf("ZERO\n");
                break;
            }
            s = transmit();
            if(dict.count(s)){
                yes = 0;
                printf("LOOP\n");
                break;
            }else dict[s]=1;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值