【CSDN竞赛第五期】比赛小结

参加了四期,18名,总算得到一次实物奖品,这次出成绩特别快,这个成绩也算差强人意。第3题由于比赛最后去忙其他事了来不及做,编译失败。第1题还是缺少经验有1个case(非法输入)没过。希望再接再厉,有机会进入前10名。

对比赛的建议 :1、为了公平以及规避抄袭,程序会检测切出页面和复制粘贴,但切出页面和复制粘贴的判定有时莫名其妙:比如我关弹窗会认为切出页面,在答题页面复制粘贴自己整个函数的代码也会被判定复制粘贴。当然,最后我没交卷,切出去忙其他事直到考试自动终止,是我的错哈哈。
2、对于与题意规定不符的输入,究竟输出什么呢?影响比赛时的体验。

1、题目名称:寻因找祖
寻找因子个数为n的最小整数x,n<=1000

  • 基本测试用例通过率:90%

算法是对的,为什么有一个例子没过呢?原来,题目说的n<=1000不代表输入符合范围,对于不合法的输入,输出0或者是什么?

原理如下:【CSDN竞赛第五期】比赛小结_第1张图片

import java.util.*;
class Main {
	private static final int maxn = 1000005;
	private static int[] tmp = new int[maxn];
	private static int[] rec = new int[maxn];
	private static int[] prime = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 39, 41, 43, 47, 51, 53, 57, 59, 61,
	67};
	private static int cnt = 0;
	private static double res = 0;
	private static void dfs(int pos, int val, int max)
	{
		if(val == 1)
		{
			cnt = pos;
			for(int i=1; i<pos; i++)rec[i] = tmp[i];
			return;
		}
		for(int i=1; i*i <= val && i <= max; i++)
		{
			if(val % i == 0)
			{
				if(i != 1)
				{
					tmp[pos] = i;
					dfs(pos+1, val/i, i);
				}
				if(val / i <= max && val / i != i)
				{
					tmp[pos] = val/i;
					dfs(pos+1, i, val/i);
				}
		    }
	   }
	}
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		String str_0 = scan.nextLine().trim();
		int n = Integer.parseInt(str_0);
		
		scan.close();
		dfs(1, n, n);
		long result = 1;
		for(int i=1; i<cnt; i++)
		{
			for(int j=1; j<rec[i]; j++)
			{
				result *= (long)prime[i];
			}
		}
		System.out.println(result);
	}
}

2、题目名称:通货膨胀-x国货币
X国发行货币最高面额为n。 次高面额为n的因子。 以此类推。 X国最多发行多少种货币。

  • 基本测试用例通过率:100%

模拟即可,循环找次高因子。比如n=6时,6、3、1,最多发行3种货币。

import java.util.ArrayList;
import java.util.Scanner;
class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		String str_0 = scan.nextLine().trim();
		int n = Integer.parseInt(str_0);
		scan.close();
		int result = solution(n);
		System.out.println(result);
	}
	public static int solution(int n){
		int result = 0;
		while(n != 1)
		{
			result++;
			for(int i=2; i<=n; i++)
			{
				if(n % i == 0)
				{
					n /= i;
					break;
				}
			}
		}
		result++; //n=1
		return result;
	}
}

3、题目名称:莫名其妙的键盘
有一个神奇的键盘,你可以用它输入a到z的字符,然而每当你输入一个元音字母(a,e,i,o,u其中之一)的时候,已输入的字
符串会发生一次反转! 比方说,当前输入了tw,此时再输入一个o,此时屏幕上的字符串two会反转成owt。 现给出一个字符串,若用该键盘输入,有多少种方法可以得到?

基本测试用例通过率:0%

做这题时还有至少半小时,有点思路,无奈中途有事,打了个草稿回来,试卷自动提交了,编译错误。
写个递归程序(可能不会100%通过,至少不会0分),比赛后没有提交的地方可验证学习。
我的思路: 目标字符串要么直接输入最后一个字符得到,要么输入最后一个字符后反转得到。
直接输入最后一个字符得到时,目标最后一个字符不能是元音字母。
输入最后一个字符后反转得到,目标第一个字符是元音字母。

	public static int solution(String str){
		// TODO: 请在此编写代码
		if(str == null) return 0;
		int len = str.length();
		if(len == 0) return 0;
		if(len == 1) return 1;
		int ans = 0;
		//有反转,第一个字母一定元音字母
		if(isVow(str.charAt(0)))
		{
			String newStr = new StringBuilder(str).reverse().toString().substring(0, len-1);
			ans += solution(newStr);
		}
		//没有反转,最后一个字母不是元音字母
		if(!isVow(str.charAt(len-1)))
		{
			ans += solution(str.substring(0, len-1));
		}
		return ans;
	}
	private static boolean isVow(char c)
	{
		return "aeiou".indexOf(c) != -1;
	}

4、题目名称:三而竭
一鼓作气再而衰三而竭。 小艺总是喜欢把任务分开做。 小艺接到一个任务,任务的总任务量是n。 第一天小艺能完成x份
任务。 第二天能完成x/k。 。。。 第t天能完成x/(k^(t-1))。 小艺想知道自己第一天至少完成多少才能完成最后的任务。

  • 基本测试用例通过率:100%

二分查找。查找的范围为1~n。找到最小的x,使得能完成任务。也即是二分查找的左边界。

import java.util.ArrayList;
import java.util.Scanner;
class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		String str_0 = scan.nextLine();
		String[] line_list_0 = str_0.trim().split(" ");
		ArrayList<Integer> arr = new ArrayList<>();
		for(int i = 0; i < line_list_0.length; i++){
		arr.add(Integer.parseInt(line_list_0[i]));
		}
		scan.close();
		int result = solution(arr);
		System.out.println(result);
	}
	public static int solution(ArrayList<Integer> arr){
		int result = 0;
		int n = arr.get(0), k = arr.get(1);
		int left = 1, right = n;
		while(left <= right)
		{
			int mid = left + (right - left) / 2;
			if(canComp(n, k, mid))
			{
				right = mid - 1;
			}
			else left = mid + 1;
		}
		return left;
	}
	private static boolean canComp(int n, int k, int x)
	{
		int sum = 0;
		while(x > 0)
		{
			sum += x;
			x /= k;
		}
		return sum >= n;
	}
}

你可能感兴趣的:(Java编程小练习,面试编程题,算法,数据结构,CSDN竞赛)