USACO 循环数 Runaround Numbers

循环数是那些不包括0且没有重复数字的整数,并且游戏规则起点开始,经过每个数字一次(往后数数字游戏)后回到起点的就是循环数。

如果你经过每一个数字一次(数数字游戏)后,没有回到起点, 你的数字不是一个循环数。

因此,很显然循环数必定在[M,987654321]范围内

送上AC代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
 
bool arr[10];
bool exist[10];    //用于记录1,2,3...这些数字在整数num中的存在情况
unsigned int num,cnt;
int cycle[10];
 
int main()
{
    int k,len;
    int pos;
    scanf("%d",&num);
    while (true)
    {
        Begin:
        memset(arr,0,sizeof(arr));
        memset(exist,0,sizeof(exist));
        num++;         //从输入的整数下一个数字开始判断是否为循环数
        cnt=0;
        k=1;
        len=0;         //len,记录num的位数
        while (k<=num)
        {
            k=k*10;
            len++;
        }
        len--;
        k=num;
        for(pos=len;pos>=0;pos--)
        {
            if (exist[k%10]||!(k%10))  //num中存在重复的数字或者0,必定不是循环数,继续判断下一个数,goto Begin
                goto Begin;
            cycle[pos]=k%10;           //cycle[]中记录着,num中的pos位置,要往下数k%10个数字
            exist[k%10]=true;          //标记数字k%10已经在num中存在
            k=k/10;               //对于整数num是从后往前一次剥离每一位数字,在得到当前位数字后,前一位数字应为(k/10)%10
        }
        pos=0;
        //循环数,往后数数字循环游戏过程,最开始从num的第一个数字往后数数,pos=0
        while (!arr[pos])     //根据规则要求经历每个位置有且仅有一次最终回到起始位置才是循环数,判断当前位pos是否已经经历过?
        {
            arr[pos]=true;      //标识整数num当前位置已经被数过(经历过)
            pos=(pos+cycle[pos])%(len+1);  //计算下一轮数数字游戏,起始位置
            cnt++;              //游戏每数过一个位置上的数字,游戏轮数,计数cnt++
        }
        if (cnt==len+1&&pos==0)  //从起始位置开始,判断游戏的轮数是否和整数num的位数相同且最终位置回到了起始位置0
        {        //由于前面计算得到整数num的位数len后,由于数组arr[]从0开始,有一个len--操作,因此这里比较为cnt==len+1
            printf("%d",num);
            return 0;
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/zi-nai-boboyang/p/11437147.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值