[USACO]Runaround Numbers

13 篇文章 0 订阅
Runaround Numbers

Runaround numbers are integers with unique digits, none of which is zero (e.g., 81362) that also have an interesting property, exemplified by this demonstration:

  • If you start at the left digit (8 in our number) and count that number of digits to the right (wrapping back to the first digit when no digits on the right are available), you'll end up at a new digit (a number which does not end up at a new digit is not a Runaround Number). Consider: 8 1 3 6 2 which cycles through eight digits: 1 3 6 2 8 1 3 6 so the next digit is 6.
  • Repeat this cycle (this time for the six counts designed by the `6') and you should end on a new digit: 2 8 1 3 6 2, namely 2.
  • Repeat again (two digits this time): 8 1
  • Continue again (one digit this time): 3
  • One more time: 6 2 8 and you have ended up back where you started, after touching each digit once. If you don't end up back where you started after touching each digit once, your number is not a Runaround number.

Given a number M (that has anywhere from 1 through 9 digits), find and print the next runaround number higher than M, which will always fit into an unsigned long integer for the given test data.

PROGRAM NAME: runround

INPUT FORMAT

A single line with a single integer, M

SAMPLE INPUT (file runround.in)

81361

OUTPUT FORMAT

A single line containing the next runaround number higher than the input value, M.

SAMPLE OUTPUT (file runround.out)

81362
 
纠结了好半天,拼拼凑凑,缝缝补补可算是AC了。
题解:
其实就是求一个数是否为循环数:
1、有效位不能含有0;
2、不能包含重复数字,如121就是非法的;
3、循环数定义(仅限本题):从起始位开始行走,行走的步数为起始位所对应值,遇到尾则从头继续;如果遍历了全部数据且回到了起始位置,则此树为循环数。下用一个数举例:
1246895:
起始位0,值为1,从0位开始走1步,至1;
值为2,从1位开始走两步,至3;
值为6,从3位开始走6步,至2;
……
最后回到1位置,且所有数组走过且仅经过一次,说明概数为循环数。
 
写几个循环数行走,可以发现一个规则,关于如何快速判断下次落脚位置,若i为此次停止位即下次起始位,则下次的落脚位为:
(i+1)=(i+round[i])/round.length;
剩下的就是一些细节上的判断。
 
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class runround {
    public static void main(String[] args) throws IOException,FileNotFoundException {
	BufferedReader br = new BufferedReader(new FileReader("runround.in"));
	FileWriter fout = new FileWriter("runround.out");
	String M = br.readLine();
	int m = Integer.parseInt(M);
	boolean isRunAound = false;
	while(!isRunAound) {
	    	m=increase(m);
	    	M = new String(""+m);
	    	char[] chars = M.toCharArray();
		int start = 0;
		int[] touched = new int[chars.length];
		touched[0]=1;
		int i ;
        	for(i = 1;i<=chars.length;i++) {
        	    start = (start+chars[start]-'0')%chars.length;
        	    if(touched[start]==1) {
        		break;
        	    }else {
        		touched[start]=1;
        	    }
        	}
        	if(i==chars.length&&start==0) {
        	    break;
        	}
	}
	fout.write(m+"\n");
	fout.flush();
	fout.close();
	br.close();
	System.exit(0);
    }

    private static int increase(int m) {
	while(!check(++m)){
	}
	return m;
    }

    private static boolean check(int i) {
	int[] digits = new int[10];
	while(i>0) {
	    if(i%10==0||digits[(i%10)-1]==1) {
		return false;
	    }
	    digits[(i%10)-1]=1;
	    i/=10;
	}
	return true;
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值