编程之美2014挑战赛 复赛 Codehunt平台试题答案
首先介绍一下CodeHunt这个平台,题目是一些数据,或者说是测试用例,你的编程结果只要保证能让测试用例通过测试即可。
https://www.codehunt.com/ 没事的同学可以进去看看,可以用各种账号登录,只是不能访问到编程之美2014挑战赛的试题罢了。
P.S. 服务器托管在国外的Azure,可能会访问较慢
每次仅给出很少的测试用例,当且仅当你的程序让这些测试用例通过测试并有未通过测试的用例时才会给你错误提示。
通过测试的代码,平台会根据代码质量给出1,2,3等级的评分,我仅一道题为1,其他均为满分3分。
本次比赛分为Fire,Metal,Earth三个模块,每个模块难度不同。
Fire 01 为指导,并不是真题。
Fire 02,03非常简单,仅列出答案
using System; public class Program { public static int Puzzle(int[] a) { return a[0]; } }
using System; public class Program { public static int Puzzle(int n) { return n+(4-n%4)%4; } }
- Fire 04
Fire 04 这道题我仅得了一分,这道题要把一个字符串中的数字提取出来生成一个新的字符串,以下是我的某3种方法。求高人指导更好的方法!!顺便求解错误方法错在哪?
s | ans |
p | |
0 | 0 |
<: | |
0 | 0 |
"0 " | 0 |
000p00 | 0 |
3 | 3 |
5 | 5 |
p0 | 0 |
using System; using System.Linq; public class Program { public static string Puzzle(string s) { return new string(c.Where(i => i >= '0' && i <= '9').ToArray()); } }
using System; using System.Text.RegularExpressions; public class Program { public static string Puzzle(string s) { Regex regexpattern = new Regex(@"[0-9]*"); string ans=""; foreach (Match match in regexpattern.Matches(s)) { ans+= match.Value; } return ans; } }
using System; public class Program { public static string Puzzle(string s) { string ss = ""; for (int i = 0; i < s.Length; i++) { if (s[i] >= '0' && s[i] <= '9') { ss += s[i]; } } return ss; } }
如果s==“p0”,下面的代码无法正常运行,求解释! public static string Puzzle(string s) { return new string(s.TakeWhile(i => i >= '0' && i <= '9').ToArray()); }
- Metal 01
s | ans |
\0\0\0\0 | \0\0\0\0 |
/\0\0/ | /\0\0/ |
/*\0\0 | /*\0\0 |
/\0/*/// | /\0/*/// |
/\u0a00/* | /\u0a00/* |
/**/* | * |
\0/**// | \0 / |
/\0/**// | /\0 / |
思路:乍一看确实不知道是什么,仔细看,发现把“/**/”都换成了空格,那么我准备考虑是不是删掉字符串中的注释内容。但实际上,这题仅是一个简单替换而已。
using System; public class Program { public static string Puzzle(string s) { return s.Replace("/**/", " "); ; } }
- Metal 02
a | b | ans |
1 | 1 | 1 |
2 | 2 | 2 |
65 | 32 | 2080 |
23 | 14 | 322 |
思路:就是求最小公倍数
提示:用乘积除以最大公因数
如果最大公因数求解过程中使用辗转相除法的话得分是2分!
using System; public class Program { public static int Puzzle(int a, int b) { int mul = a * b; while (a != b) { if (a > b) a = a - b; if (b > a) b = b - a; } return mul / a; } }
- Metal 03
a | ans |
{0,0} | null |
{0,0,0} | null |
{0,0,0,0} | null |
{0,0,0,0,0} | 0 |
{17,4,23,13,-9} | 4 |
{18,18,18,18,18} | 0 |
{50,18,18,18,18} | 32 |
思路:注意到a的长度达到5后就有结果了,否则会提示应该throw IndexOutOfRangeException。
对于长度大于等于5数组,结果是该数组间两个数差值的最小值。
最开始用 a=a.OrderBy(item=>item)排序,但平台提示出错。(已经引用System.Linq)
using System; using System.Linq; public class Program { public static int Puzzle(int[] a) { if (a.Length <= 4) throw new IndexOutOfRangeException(); int min = int.MaxValue; for (int i = 0; i < a.Length; i++) { for (int j = i + 1; j < a.Length; j++) { int b = Math.Abs(a[i] - a[j]); min = Math.Min(min, b); } } return min; } }
- Earth 01
a | b | c | ans |
0 | 0 | 1 | 0 |
916 | 914 | 49 | 10 |
3 | 4 | 5 | 2 |
7 | 13 | 4 | 3 |
3 | 522 | 411 | 333 |
3 | 4 | 1 | 0 |
3 | 0 | 1 | 0 |
916 | 914 | 1 | 0 |
916 | 0 | 1 | 0 |
1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 |
思路:注意到(3,522,411)这一组,很容易发现 ans=a*(b-c),但是(916,914,49)这组好像不对,取个余数,就得到 ans=(a*(b-c))%c,如果b<c就出现负数,而C#中取余的符号和前者相同,这时要进行相应处理。
using System; public class Program { public static int Puzzle(int a, int b, int c) { return (((a * (b - c))) % c + c) % c; } }
- Earth 02
n | ans |
0 | 0 |
1 | 1 |
12 | 2 |
13 | 3 |
20 | 2 |
34 | 2 |
512 | 1 |
256 | 1 |
128 | 1 |
64 | 1 |
32 | 1 |
16 | 1 |
8 | 1 |
4 | 1 |
2 |
1 |
思路:发现所有2的指数幂都是1,而12=8+4,2个数相加;13=8+4+1,3个数相加。
则认为是n的二进制表示中1的个数。
using System; public class Program { public static int Puzzle(int n) { int ans = 0; while (n > 0) { if (n % 2 == 1) { ans++; } n /= 2; } return ans; } }
- Earth 03
v1 v2 ans {} {} 0 {0} {0} 0 {0} {7} 49 {8} {9} 1 {8,0} {9,0} 1 {0,0} {0,0} 0 {8,8} {9,9} 2
思路,如果定义距离为对应元素的平方和的话,ans就是v1和v2的距离。
using System; public class Program { public static int Puzzle(int[] v1, int[] v2) { int sum = 0; for (int i = 0; i < v1.Length; i++) { sum += Math.Abs(v1[i] - v2[i]) * Math.Abs(v1[i] - v2[i]); } return sum; } }