Runaround Numbers

Problem:

http://ace.delos.com/usacoprob2?a=GDaP3qeGiYp&S=runround


Answer:

/*
ID:iby071
TASK:runround
LANG:C++
*/

#include<iostream>
#include<fstream>
using namespace std;

bool check(unsigned long int n)
{	int digit=0,k;
	int num[20];
	bool visited[20];
	bool makeup[10];
	unsigned long int tmp=n;

	for(int i=0;i<10;++i)
		makeup[i]=false;

	while(tmp!=0)							//这里生成的num[]是逆序的
	{	num[digit]=tmp%10;
		if(num[digit]==0 || makeup[num[digit]]) return false;			//循环数组成中不能有0,不能有重复数字
		makeup[num[digit]]=true;
		tmp/=10;
		++digit;
	}	

	for(int i=0;i<digit;++i)
		visited[i]=false;
	
	k=digit-1;
	visited[digit-1]=true;
	for(int i=0;i<digit;++i)
	{	k=((k-num[k]%digit)+digit)%digit;			//mod原因:从下标k向左num[k]次会越界;第一次mod:num[k]>=digit;第二次mod:num[k]>k
		if(visited[k]) break;
		visited[k]=true;
	}
	
	if(k!=digit-1) return false;			//没有回到初始位置,不是循环数
	for(int i=0;i<digit;++i)
		if(!visited[i]) return false;			//在digit次访问中,有些位没被访问,不是循环数
	return true;
}

int main()
{	ifstream fin("runround.in");
	ofstream fout("runround.out");
	unsigned long int m,n;
	fin>>m;

	for(n=m+1; ;++n)
		if(check(n)) {fout<<n<<endl;break;}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值