前言
简单记录一下笔试情况。
一、转换整数
题目简介
汉宁窗公式 :H(n)=0.5*(1-cos(2PIn/N)),N 为窗长度,0<= n < N,PI=3.1415927。对任意长度为 N 的双字节整数序列 x(n),加窗之后 y(n) =x(n) *H(n)。
即输入一个整数序列,对其按照上面的公式做一个转换即可。要求对输出 y(n) 四舍五入取整数部分。{正数: int(x+0.5) 负数:int(x-0.5) }
代码实现
输入数据:32
1953 2347 16 -1042 -1546 -933 -1946 -2722 -427 2111 3260 -1265 -8196 -8766 -2922 4135 6564 4644 2726 2789 4939 4451 149 -2320 -1348 2211 3370 900 -886 -1998 -643 172
输出数据:0 23 1 -88 -226 -207 -601 -1095 -214 1261 2254 -984 -6996 -8027 -2811 4095 6564 4599 2622 2554 4216 3462 103 -1386 -674 890 1040 200 -130 -168 -24 2
import java.util.Scanner;
public class Main1 {
static double PI=3.1415927;
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
int N=s.nextInt();
int[] res=new int[N];
for(int i=0;i<N;i++){
int tmp=s.nextInt(); // tmp -> x(i)
double d=tmp*(0.5*(1-Math.cos(2*PI*i/N)));// 计算 d -> y(i)
if(d>0)
d+=0.5;
else if(d<0)
d-=0.5;
res[i]=(int)d; //四舍五入 取整保存在 res 中。
}
for(int i=0;i<N-1;i++) // 注意输出格式
System.out.print(res[i]+" ");
System.out.println(res[N-1]);
}
}
二、判断三角形个数
题目简介
二维坐标上有 N 个点,任意一个点都可能构成三角形,计算这些三角形中直角三角形的个数。
暴力枚举:遍历所有三个点构成的组合,判断是否满足勾股定理。后面采用 for 循环和回溯分别来实现。
输入数据:20
0 0 0 3 1 2 3 4 5 6 7 8 1 4 2 4 3 5 5 0 5 5 2 0 2 2 3 0 3 3 4 5 6 1 3 7 4 0 5 2
输出数据:165
代码实现1
import java.util.Scanner;
public class Main2 {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
int N=s.nextInt();
int[][] pos=new int[260][2];// N <=256
for(int i=0;i<N;i++){
pos[i][0]=s.nextInt();
pos[i][1]=s.nextInt();
}
int res=0;
for(int i=0;i<N-2;i++)
for(int j=i+1;j<N-1;j++)
for(int k=j+1;k<N;k++){
// x, y, z 分别为三条边的平方。
// A(x1,y1)、B(x2,y2),则A和B两点之间的距离为:∣AB∣=√[(x1-x2)^2+(y1-y2)^2]
double x=Math.pow(pos[i][0]-pos[j][0],2)+Math.pow(pos[i][1]-pos[j][1],2);
double y=Math.pow(pos[j][0]-pos[k][0],2)+Math.pow(pos[j][1]-pos[k][1],2);
double z=Math.pow(pos[i][0]-pos[k][0],2)+Math.pow(pos[i][1]+-pos[k][1],2);
int xx= (int) x,yy=(int) y,zz=(int) z;
if(x+y==z||x+z==y||y+z==x)
res++;
}
System.out.println(res);
}
}
代码实现2
将上面的求组合用回溯来实现(好久没写回溯了,练习一下)
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main2 {
static int res=0;
static List<int[]> tmp=new ArrayList<>(3);
private static void getRes(int[][] pos,int cur,int N){
if(tmp.size()==3){
// 打印每一次的组合情况
// for(int[] t:tmp){
// System.out.print(t[0]+" "+t[1]+" ");
// }
// System.out.println();
int x=(tmp.get(0)[0]-tmp.get(1)[0])*(tmp.get(0)[0]-tmp.get(1)[0])
+(tmp.get(0)[1]-tmp.get(1)[1])*(tmp.get(0)[1]-tmp.get(1)[1]);
int y=(tmp.get(0)[0]-tmp.get(2)[0])*(tmp.get(0)[0]-tmp.get(2)[0])
+(tmp.get(0)[1]-tmp.get(2)[1])*(tmp.get(0)[1]-tmp.get(2)[1]);
int z=(tmp.get(1)[0]-tmp.get(2)[0])*(tmp.get(1)[0]-tmp.get(2)[0])
+(tmp.get(1)[1]-tmp.get(2)[1])*(tmp.get(1)[1]-tmp.get(2)[1]);
if(x+y==z||x+z==y||y+z==x)
res++;
return;
}
for(int i=cur;i<N;i++){
tmp.add(pos[i]);
getRes(pos,i+1,N);
tmp.remove(tmp.size()-1);
}
}
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
int N=s.nextInt();
int[][] pos=new int[260][2];// N <=256
for(int i=0;i<N;i++){
pos[i][0]=s.nextInt();
pos[i][1]=s.nextInt();
}
//简单的测试用例:
// int[][] pos=new int[][]{{0,0},{0,3},{1,2},{3,4},{5,6}};
// int N=pos.length;
getRes(pos,0,N);
System.out.println(res);
}
}
简单的图示如下:
在五个数中取 三个数构成的组合 ,上面的回溯代码思路如下图所示:
三、计算球队得分情况
题目简介
有5支球队,进行单循环比赛,每个球队都只和另一只球队打一场。一共10场比赛,求有多少种得分情况(得分情况降序排列,需要去重)?以及给定一组得分情况,判断其是否合理?
回溯 ,依次来判断,每场比赛只有三种可能性,one Vs another, 要么赢,要么输,要么平。
代码实现
import java.util.*;
public class Main3 {
final static int Teams=5; //有五只队伍
final static int Rounds=10; // 轮次有10场, 每支队伍只和其余队伍打一场
static HashSet<List<Integer>> set=new HashSet<>(); // 存放得分信息的 set
static int[][] r=new int[Rounds][2]; // 每一场比赛的参赛队伍
static HashMap<Integer,Integer> scoreOfTeam=new HashMap<>();// 用来记录每种得分情况
private static void compute(int start){
if(start==Rounds){
List<Integer> l=new ArrayList<>();
for(int i:scoreOfTeam.values())
l.add(i);
l.sort((a, b) -> {
return b - a;
}); //降序排列
set.add(l);
}
for(int i=start;i<Rounds;i++){
int one=r[i][0],another=r[i][1];
// one 赢 another
scoreOfTeam.put(one,scoreOfTeam.get(one)+3);
scoreOfTeam.put(another,scoreOfTeam.get(another)+0);// 这一步可以省略
compute(i+1);
// one 输 another
scoreOfTeam.put(one,scoreOfTeam.get(one)-3);
scoreOfTeam.put(another,scoreOfTeam.get(another)+3);
compute(i+1);
// one 平 another
scoreOfTeam.put(one,scoreOfTeam.get(one)+1);
scoreOfTeam.put(another,scoreOfTeam.get(another)-2);
compute(i+1);
// 复原 reset
scoreOfTeam.put(one,scoreOfTeam.get(one)-1);
scoreOfTeam.put(another,scoreOfTeam.get(another)-1);
}
}
public static void main(String[] args) {
// 初始化 r, 参赛队伍信息。 参赛队伍为: 0 1 2 3 4
int index=0;
for(int i=0;i<Teams;i++){ // 这里也可以写成 i<Teams-1;
for(int j=i+1;j<Teams;j++){
r[index][0]=i;
r[index][1]=j;
index++;
}
}
// 初始化 hashMap, 刚开始每只队伍得分均为 0
for(int i=0;i<Teams;i++)
scoreOfTeam.put(i,0);
compute(0);
System.out.println(set.size());
List<Integer> input=new ArrayList<>(Arrays.asList(6,5,5,5,4));
System.out.println(set.contains(input));
}
}
集合去重
关于集合去重,运行下面测试代码查看输出即可。
public static void main(String[] args) {
HashSet<List<Integer>> set=new HashSet<>();
List<Integer> input1=new ArrayList<>(Arrays.asList(6,5,5,5,4));
List<Integer> input2=new ArrayList<>(Arrays.asList(6,5,5,5,4));
set.add(input1);
set.add(input2);
System.out.println(set);
System.out.println(set.contains(input1));
System.out.println(set.contains(input2));
}
总结
完