本次在線測試包含兩道題目,難度跟通知時說明的一樣,LeetCode中等難度。
由於題目相對簡單,我就直接放題目,然後給出參考答案,雖然測試時都AC了,但我覺得大家可能還有更好的答案。
歡迎交流,提供更多有趣的優化算法。
No.1 勾股數元祖
題目描述:
也稱爲 “素勾股數” ,其有以下性質:
本題需要注意的是,
多組勾股數元祖請按照按a升序,b升序,最後c升序的方式輸出。
源程序:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
using namespace std;
#include <math.h>
/* 判斷兩個數字是否互質,返回值是1時表明互質,其它值則不互質 */
int is_coprime(int src1,int src2)
{
if(0 == src2)
return src1;
else
return is_coprime(src2,src1%src2);
}
void printResult(int a, int b, int c)
{
//print the three number orderedly
if(a<b && b<c)
printf("%d %d %d\n",a,b,c);
else if(a>b && b>c)
printf("%d %d %d\n",c,b,a);
else if(b<c && a>c)
printf("%d %d %d\n",b,c,a);
else
printf("%d %d %d\n",b,a,c);
}
int funcation(int N, int M)
{
int countor = 0;
int m = 0;
if(0 < N && N < M)
m = sqrt(M);
else
return -1;
for(int i = N; i <= M; i++)
{
for(int j = i+1; j <= M; j++)
{
for(int k = j+1; k <= M; k++)
{
if(i*i + j*j == k*k)
{
if(1 == is_coprime(i,j) && 1 == is_coprime(i,k) && 1 == is_coprime(j,k))
{
countor++;
printResult(i,j,k);
//printf("%d %d %d\n",a,b,c);
}
}
}
}
}
if(countor == 0)
printf("NA");
return 0;
}
int main()
{
int N=0,M=0;
scanf("%d %d",&N,&M);
funcation(N, M);
return 0;
}
備註:用了一種十分愚蠢的辦法,不管時間複雜度多高,三七二十一來個遍歷,所有問題都可以遍歷到。我也是考試時沒辦法了,我在考慮用這個性質的時候,打印的結果總是不滿足第二條,只通過了37.5%。無奈之下,我提交了這個垃圾的程序。
另外,本題目之前有原題,只不過他只要找到小於N的素勾股數的對數,因此這個性質就十分好用。歡迎大家給我的程序提提意見, 現在忙着畢業設計也沒時間繼續改進。
參考題目:
華爲機試——素勾股數
/***************************************************************
* 題目:勾股數,是由三個正整數組成的數組;能符合勾股定理 a*a + b*b = c*c ,(a, b, c) 的正整數解。
* 如果 (a, b, c) 是勾股數,它們的正整數倍數,也是勾股數。
* 如果 (a, b, c) 互質,它們就稱爲素勾股數。
* 給定正整數N, 計算出小於或等於N的素勾股數個數。
* 輸入描述:輸一個正整數
* 輸出描述:素勾股數
* 示例輸入:10
* 示例輸出:1
***************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
/* 判斷兩個數字是否互質,返回值是1時表明互質,其它值則不互質 */
int is_coprime(int src1,int src2)
{
if(0 == src2)
return src1;
else
return is_coprime(src2,src1%src2);
}
int main()
{
int input=0;
int i,j;
int a,b,c;
int countor=0;
scanf("%d",&input);
if(0 < input)
m = sqrt(input);
else
return -1;
for(i=1;i<=input;i++)
{
for(j=i+1;j<=input;j++)
{
a = j * j - i * i;
b = 2 * i * j;
c = i * i + j * j;
if(c <= input)
{
if(1 == is_coprime(a,b) && 1 == is_coprime(b,c) && 1 == is_coprime(a,c))
{
countor++;
printf("a=%d,b=%d,c=%d\n",a,b,c);
}
}
}
}
printf("%d\n",countor);
return 0;
}
這邊還有cutter_point提供的java解決辦法
,供小夥伴們參考。
package y2020.interview.huawei.gougushu;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @Auther: xiaof
* @Date: 2020/3/11 10:25
* @Description:勾股數元祖 素勾股數的個數
*
* 勾股數,是由三個正整數組成的數組;能符合勾股定理 a*a + b*b = c*c ,(a, b, c) 的正整數解。如果 (a, b, c) 是勾股數,
* 它們的正整數倍數,也是勾股數。如果 (a, b, c) 互質,它們就稱爲素勾股數。給定正整數N, 計算出小於或等於N的素勾股數個數。
*
*/
public class Main {
public static List solution(int n, int m) {
List res = new ArrayList();
for (int a = n; a <= m - 2; ++a) {
for (int b = a + 1; b <= m - 1; ++b) {
//求c
double c = Math.sqrt(Math.pow(a,2) + Math.pow(b,2));
long cz = (long) c;
if (c - cz == 0 && c <= m && isPrim(a,b) && isPrim(a, (int) c) && isPrim(b, (int) c)) {
res.add(new int[]{a, b, (int) c});
} else if (c > m) {
break;
}
}
}
return res;
}
//判斷a,b,c互質
public static boolean isPrim(int a, int b) {
if(a < b) {
int tmp = a;
a = b;
b = tmp;
}
int c;
//輾轉相除
while((c = a % b) != 0) {
a = b;
b = c;
}
return b == 1;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
List<int[]> res = solution(n, m);
res.forEach(res1 -> {
System.out.println(res1[0] + " " + res1[1] + " " + res1[2]);
});
}
}
好了,第一題就算結束了。
No.2 磁盤大小比較
題目描述:
磁盤的容量單位有M、G、T,其關係爲 1T = 1000G、1G = 1000M,如樣例所示先輸入磁盤的個數,再依次輸入磁盤的容量大小,然後按照從小到大的順序對磁盤容量進行排序並輸出。
輸入樣例:
3
20M
1T
3G
輸出樣例:
20M
3G
1T
這個代碼我忘了保存,後來的程序如下:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int StrToInt(string str)
{
if (str[str.size() - 1] == 'M') {
return stoi(str.substr(0, str.size() - 1));
} else if (str[str.size() - 1] == 'G') {
return stoi(str.substr(0, str.size() - 1)) * 1000;
} else if (str[str.size() - 1] == 'T') {
return stoi(str.substr(0, str.size() - 1)) * 1000000;
}
return 0;
}
bool Compare(const string &strA, const string &strB)
{
int a = StrToInt(strA);
int b = StrToInt(strB);
// 升序排序
return a < b;
}
int main(void)
{
int n;
while (cin >> n) {
string str;
vector<string> vec;
while (n--) {
cin >> str;
vec.push_back(str);
}
sort(vec.begin(), vec.end(), Compare);
for (auto i : vec) {
cout << i << endl;
}
}
return 0;
}
同樣地,我也找了拉格朗宇的Java源程序供大家參考。
package Huawei;
import java.util.Scanner;
/**
* Created by xuzhenyu on 2020/1/5.
*/
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
String[] strings = new String[n];
for (int i = 0; i < n; i++) {
strings[i] = scanner.next();
}
String[] ruslutStrs = sort(strings);
for (int i = 0; i <ruslutStrs.length ; i++) {
System.out.println(ruslutStrs[i]);
}
}
private static String[] sort(String[] strs) {
for (int i = 0; i < strs.length - 1; i++) {
for (int j = 0; j < strs.length - i - 1; j++) {
// M G T
if (compare(strs[j], strs[j + 1])) {
String tem = strs[j];
strs[j] = strs[j+1];
strs[j+1] = tem;
}
}
}
return strs;
}
private static boolean compare(String str1, String str2){
int str1M = turnString(str1);
int str2M = turnString(str2);
return str1M>str2M;
}
private static int turnString(String str){
if("M".equals(String.valueOf(str.charAt(str.length()-1)))){
return Integer.parseInt(str.substring(0,str.length()-1));
}
else if ("G".equals(String.valueOf(str.charAt(str.length()-1)))){
return Integer.parseInt(str.substring(0,str.length()-1))*1000;
}
else if ("T".equals(String.valueOf(str.charAt(str.length()-1)))){
return Integer.parseInt(str.substring(0,str.length()-1))*1000000;
}
return 0;
};
}
推薦閱讀:
[1] 數據結構與算法 | 你知道快速排序,那你知道它的衍生應用嗎?Partition函數
[2] 數據結構與算法 | 數據結構中到底有多少種“樹”?一文告訴你
[3] 數據結構與算法 | 二分查找:劍指offer53 在排序數組中查找數字
關注微信公衆號:邁微電子研發社,回覆獲取更多精彩內容。
知識星球:社羣旨在分享AI算法崗的秋招/春招準備攻略(含刷題)、面經和內推機會、學習路線、知識題庫等。