网易编程题(2)

一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的)。如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积。
例如:如果袋子里面的球的号码是{1, 1, 2, 3},这个袋子就是幸运的,因为1 + 1 + 2 + 3 > 1 * 1 * 2 * 3
你可以适当从袋子里移除一些球(可以移除0个,但是别移除完),要使移除后的袋子是幸运的。现在让你编程计算一下你可以获得的多少种不同的幸运的袋子。 

输入描述:
第一行输入一个正整数n(n ≤ 1000)
第二行为n个数正整数xi(xi ≤ 1000)


输出描述:
输出可以产生的幸运的袋子数

输入例子:
3
1 1 1

输出例子:
2

思路:DFS + 剪枝

/*
 * DFS,剪枝:当某个时候sum<mul,后面再加任何数sum都不会比mul大(在数组是排好序的情况下)
 */
public class Main {
	static int cnt = 0;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[]a = new int[n];
		for(int i=0; i<n; i++)a[i]=sc.nextInt();
		Arrays.sort(a);
		
		dfs(a, 0, 0, 0, 1);
		System.out.println(cnt);
	}

	private static void dfs(int[] a, int start, int k, int sum, int mul) {
		if(k >= 2) {
			if(sum > mul) 	cnt++;
			else 		  	return;
		}
		for(int i=start; i<a.length; i++) {
			if(i!=start&&a[i]==a[i-1])continue;
			dfs(a, i+1, k+1, sum+a[i], mul*a[i]);
		}
		
	}

}




小易总是感觉饥饿,所以作为章鱼的小易经常出去寻找贝壳吃。最开始小易在一个初始位置x_0。对于小易所处的当前位置x,他只能通过神秘的力量移动到 4 * x + 3或者8 * x + 7。因为使用神秘力量要耗费太多体力,所以它只能使用神秘力量最多100,000次。贝壳总生长在能被1,000,000,007整除的位置(比如:位置0,位置1,000,000,007,位置2,000,000,014等)。小易需要你帮忙计算最少需要使用多少次神秘力量就能吃到贝壳。 

输入描述:
输入一个初始位置x_0,范围在1到1,000,000,006


输出描述:
输出小易最少需要使用神秘力量的次数,如果使用次数使用完还没找到贝壳,则输出-1

输入例子:
125000000

输出例子:
1
思路:主要是要看出来   4 * x + 3就是左移2位,右边补1,,8 * x + 7就是左移3位,右边补1。我们就假设移位的位数能覆盖所有的整数范围,即0-300000,因为要移的次数最少,那就先以3位的速度移动,同时判断2位,3位之外有没有满足条件的。

其实也可以先求出总的移动步数,在分摊到2,3步上面!

package l14;

import java.util.*;

/*
 * 要么左移2位补1,要么右移3位补1
 * 以移3位的step前进,在每一步判断当前位,左移2位,左移4位满不满足条件
 */
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long a = (long)sc.nextInt();
		if((4*a+3)%1000000007 == 0) {
			System.out.println(1);
			return;
		}
		
		int cnt=0;
		while(cnt < 100000) {
			if(a%1000000007 == 0) {
				System.out.println(cnt);
				return;
			}
			if((4*a+3)%1000000007 == 0) {
				System.out.println(cnt+1);
				return;
			}
			if((4*(4*a+3)+3)%1000000007 == 0) {
				System.out.println(cnt+2);
				return;
			}
			
			cnt++;
			a = (8*a+7)%1000000007;
		}
		
		System.out.println(-1);
	}

}

其实用BFS也可以,但是要用HashTable剪纸,但是我写的老是用例通不过,暂时还没有找到bug

package l14;

import java.util.*;

public class CopyOfMain {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long a = (long)sc.nextInt();
		int cnt=0;
		Set<Long>s = new HashSet<Long>();
		Set<Long>ss= new HashSet<Long>();
		s.add(a);
		boolean f=false;
		
		while(true) {
			for(long i : s) {
				// 添加4*i+3与(4*i+3)%1000000007效果一样
				long add1 = (4*i+3)%1000000007;
				long add2 = (8*i+7)%1000000007;
				cnt++;
				
				if(cnt == 99999) {
					System.out.println();
				}
				
				if(add1 == 0 || add2 == 0) {
					f = true;
					break;
				}
				ss.add(add1);
				ss.add(add2);
			}
			
			s=ss;
			ss=new HashSet<Long>();
			if(cnt>=100000 || f) break;
		}
		
		if(f) System.out.println(cnt);
		else System.out.println(-1);
	}

}








小易喜欢的单词具有以下特性:
1.单词每个字母都是大写字母
2.单词没有连续相等的字母
3.单词没有形如“xyxy”(这里的x,y指的都是字母,并且可以相同)这样的子序列,子序列可能不连续。
例如:
小易不喜欢"ABBA",因为这里有两个连续的'B'
小易不喜欢"THETXH",因为这里包含子序列"THTH"
小易不喜欢"ABACADA",因为这里包含子序列"AAAA"
小易喜欢"A","ABA"和"ABCBA"这些单词
给你一个单词,你要回答小易是否会喜欢这个单词。 

输入描述:
输入为一个字符串,都由大写字母组成,长度小于100


输出描述:
如果小易喜欢输出"Likes",不喜欢输出"Dislikes"

输入例子:
AAA

输出例子:
Dislikes
思路:注意以下代码

						int idx1=s.substring(j+1).lastIndexOf(cs[j]);
						int idx2=s.substring(j+1).indexOf(cs[i]);
						if(idx1!=-1&&idx2!=-1&& idx1>idx2 ) {
							System.out.println("Dislikes");
							return;
						}


		boolean[] firstVisited=new boolean[26];
		for(int i=0;i<n;i++) {
			if(!firstVisited[cs[i]-'A'] && cnt[cs[i]-'A']>=2) {
				firstVisited[cs[i]-'A']=true;
				for(int j=i; j<n; j++) {
					if(cs[j]!=cs[i] && cnt[cs[j]-'A']>=2) {
						int idx1=s.substring(j+1).lastIndexOf(cs[j]);
						int idx2=s.substring(j+1).indexOf(cs[i]);
						if(idx1!=-1&&idx2!=-1&& idx1>idx2 ) {
							System.out.println("Dislikes");
							return;
						}
					}
				}
			}
		}




小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和的数字中的最小数。 

输入描述:
输入第一行为数字个数n (n ≤ 20)
第二行为n个数xi (1 ≤ xi ≤ 100000)


输出描述:
输出最小不能由n个数选取求和组成的数

输入例子:
3
5 1 2

输出例子:
4
思路:不能用DFS,会TLE,原题来自Google,真会玩

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[]a = new int[n];
		for(int i=0; i<n; i++)a[i]=sc.nextInt();
		Arrays.sort(a);
		
		int miss = 1;
		for(int i : a) {
			if(i > miss)	break;
			miss += i;
		}
		System.out.println(miss);
	}
	

}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值