Written at the beginning:
The Blue Bridge Cup is coming. The countdown is 36 days!
Do (learn the real problem + understand the real problem + be able to do the real problem + summarize the real problem)
While (time! = 0)
April showers bring May flowers.
Strive to rush out of the provincial competition, come on!
Today, we bring the personal solutions of the two real problems of the 12th group B. if there are any mistakes, please correct them. Let's start now.
C. Straight line (the 12th real topic)
Problem solving ideas
This problem is also a mathematical problem. You need to recall the mathematical knowledge you have learned before, such as how to calculate slope and intercept.
The idea of solving the problem is to obtain all points first, and then calculate the straight line according to two different points. The oblique section formula y = kx + b and two-point formula (y1-y2) = k (x1-x2) are used, and then all k and b are obtained, and the duplicate is removed. I use HashSet to remove the duplicate
1. For the representation of point coordinates, I use x to expand 100 times to separate from y.
for(int i=0;i<=19;i++){ for(int j=0;j<21;j++){ set.add(i*100+j); } }
2. The method to obtain the x and y coordinates of points is as follows (a and b are the coordinates of points respectively)
int x1=a/100,x2=b/100,y1=a%100,y2=b%100;
3. After obtaining the x and y coordinates of the point, we can calculate the slope. Here we use the two-point formula.
int up=y1-y2,down=x1-x2; int c1=gcd(up,down); String k=(up/c1)+" "+(down/c1);//What I'm looking for here is the slope, which means it's a little strange. It's the difference between x and y
Here we also need to use the maximum common divisor, because for example, up=4, down=2, and up=8, down=4, the calculated slope is the same, and the values in these two cases may appear on a straight line.
//The return value is the maximum common divisor of a and b int gcd(int a,int b){ return b == 0 ? a:gcd(b,a%b); }
4. We will also discuss the case where the slope does not exist separately.
if(down==0){//Judge the straight line with non-existent slope count++;//This variable is used by me to count how many lines are perpendicular to the x-axis, and the ans of HashSet type is used to remove the duplication ans.add("x="+x1); continue; }
5. Next, let's calculate the intercept.
//The following steps will involve the two-point formula and point oblique formula of the linear equation. Pay attention to the combination of these two formulas, otherwise you may be a little confused after watching the meeting at first sight //Above, we calculate the slope. Let's bring in a point to find the intercept int kb=y1*down-up*x1; int c2=gcd(kb,down); String B=(kb/c2)+" "+(down/c2);//It's the intercept ans.add(k+" "+B);//(K + "" + b) such a string is used to represent a straight line
Complete code
public static int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } static int count=0; public static void main(String[] args) { HashSet<Integer> set=new HashSet<>(); HashSet<String> ans=new HashSet<>(); for(int i=0;i<=19;i++){ for(int j=0;j<21;j++){ set.add(i*100+j); } } List<Integer> arr=new ArrayList<>(set); int len=arr.size(); for(int i=0;i<len;i++){ int a=arr.get(i); for(int j=i+1;j<len;j++){ int b=arr.get(j); int x1=a/100,x2=b/100,y1=a%100,y2=b%100; int up=y1-y2,down=x1-x2; int c1=gcd(up,down); String k=(up/c1)+" "+(down/c1);//What I'm looking for here is the slope, which means it's a little strange. It's the difference between x and y if(down==0){//Judge the straight line with non-existent slope count++; ans.add("x="+x1); continue;//Add in the lines perpendicular to the x-axis. There should be 19 lines } //The following steps will involve the two-point formula and point oblique formula of the linear equation. Pay attention to these two formulas, otherwise you may be confused at first sight //Above, we calculate the slope. Let's bring in a point to find the intercept int kb=y1*down-up*x1; int c2=gcd(kb,down); String B=(kb/c2)+" "+(down/c2); ans.add(k+" "+B); } } System.out.println(count); System.out.println(ans.size()); }
Generally speaking, the difficulty of this problem is not big, that is, we should review the mathematical knowledge before writing the problem.
E. Path (true topic of the 12th session)
Problem solving ideas
After reading the question, I was confused and familiar with it, but I didn't know it (embarrassed smile). I heard its name - the shortest path many times, and then I went to make up for a wave of methods to find the minimum path.
The Floyd method is used to solve this problem.
The idea of this algorithm is introduced below:
(1) Algorithm idea:
Floyd algorithm is a classical dynamic programming algorithm. In popular language, our goal is to find the shortest path from point I to point J. From the point of view of dynamic programming, we need to reinterpret this goal. This interpretation is the most creative essence of dynamic programming. The shortest path from any node i to any node j is no more than two possibilities: one is directly from I to j, and the other is from I through several nodes K to J. Therefore, we assume that Dis(i,j) is the shortest path distance from node u to node v. for each node K, we check whether dis (I, K) + dis (k, J) < Dis(i,j) is true. If it is true, it is proved that the path from I to K and then to j is shorter than the path from I to j directly, so we set Dis(i,j) = Dis(i,k) + Dis(k,j). In this way, when we traverse all nodes K, Dis(i,j) records the distance of the shortest path from I to J.
After knowing the algorithm to use, the problem will be easier to solve. Just apply the template of the idea of this algorithm directly (of course, the template needs to be knocked constantly to be familiar, or coding). The code is shown directly below.
Complete code
public class Question 5 path { static int[][] graph = new int[2022][2022]; static final int INF = 0x3f3f3f3f;//This number represents infinity private static void floyd() { for (int k = 1; k <= 2021; k++) { for (int i = 1; i <= 2021; i++) { for (int j = 1; j <= 2021; j++) { if (i != j && graph[i][j] > graph[i][k] + graph[k][j]) { graph[i][j] = graph[i][k] + graph[k][j]; } } } } } private static int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } public static void main(String[] args) { for (int i = 1; i <= 2021; i++) { for (int j = 1; j <= 2021; j++) { graph[i][j] = INF; } } for (int i = 1; i <= 2021; i++) { int st = Math.max(i - 21, 1);//This is because there are directly connected edges between points with difference < = 21 for (int j = st; j <= i; j++) { int div = gcd(j, i); int lcm = i * j / div;//Size of undirected edge graph[i][j] = lcm; graph[j][i] = lcm; } } floyd(); System.out.println(graph[1][2021]); // 10266837 } }
It took a while to get out.
Conclusion: it is still difficult to solve it independently at this stage. Continue to work hard.
Continue tomorrow, rush!