华为2016校招笔试试题一——删数

华为2016校招笔试试题一——删数

题目来自牛客网,感谢!

给定数字n,在按序排列的0~n-1中从0起每隔2个数删除1个数,到末尾时循环至开头继续,求最后剩下的数。

输入格式

若干行,每行输入一个n

输出格式

每行输出对应剩下的数。

输入范例

8

输出范例

6

基础思路以队列存储数据,队首每3个数将2个数接回队尾,删除另一个数,直到队列长度为1为止。

	public static int delMethod1(int n) {
		Queue<Integer> q = new LinkedList<Integer>();
		for (int i = 0; i < n; i++)
			q.add(i);
		for (int i = 0; q.size() > 1; i = (i + 1) % 3) {
			int temp = q.poll();
			if (i == 2)
				continue;
			q.add(temp);
		}
		return q.poll();
	}

如果从数学的角度上考虑这一问题,无妨记 D ( ⋅ ) D(·) D()为删数操作, I n I_n In n n n个数操作后所余下的数,显然有 I 1 = 0 I_1=0 I1=0
由于每次删数操作均使数减少一个,因此 D ( I n ) D(I_n) D(In) I n − 1 I_{n-1} In1间存在对应关系。以 n > 3 n>3 n>3的情况为例, D ( I n ) D(I_n) D(In)跳过 0 0 0 1 1 1,删去 2 2 2。若此时将 0 0 0 1 1 1补至队尾,则构成 D ( I n ) D(I_n) D(In) I n − 1 I_{n-1} In1的对应关系:

012n-3n-2
34501

从而可得到关系式 I n = ( I n − 1 + 3 ) m o d    n I_n=(I_{n-1}+3)\mod n In=(In1+3)modn,简记为 I n = ( I n − 1 + 3 ) ∣ ( n ) I_n=(I_{n-1}+3)|_{(n)} In=(In1+3)(n)
I n = ( ( ( I 1 + 3 ) ∣ ( 1 ) + 3 ) ∣ ( 2 ) + … ) ∣ ( n ) I_n=(((I_1+3)|_{(1)}+3)|_{(2)}+…)|_{(n)} In=(((I1+3)(1)+3)(2)+)(n)

此时便有

	public static int delMethod2(int n) {
		int x = 0;
		for (int i = 1; i <= n; i++)
			x = (x + 3) % i;
		return x;
	}

我的代码实现

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;

public class DelNum {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		List<Integer> list = new ArrayList<Integer>();
		String s = null;
		while (sc.hasNextLine() && !((s = sc.nextLine()).equals("")))
			list.add(Integer.parseInt(s));
		sc.close();

		for (int n : list)
			System.out.println(delMethod2(n));
	}

	public static int delMethod1(int n) {
		Queue<Integer> q = new LinkedList<Integer>();
		for (int i = 0; i < n; i++)
			q.add(i);
		for (int i = 0; q.size() > 1; i = (i + 1) % 3) {
			int temp = q.poll();
			if (i == 2)
				continue;
			q.add(temp);
		}
		return q.poll();
	}

	public static int delMethod2(int n) {
		int x = 0;
		for (int i = 1; i <= n; i++)
			x = (x + 3) % i;
		return x;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值