写在前面:
写这篇主要是复习的时候好复习(突然发现记博客的好处就是随时随地可以看,还不占空间内存),暂时只记了ABCFG这五题,如果想看所有题目的可以直接点击上面别人大佬的链接,就不用点击关注我了(设个关注仅仅只是我很菜,还是不要出来乱晃了,当然有大佬想看我的题解欢迎不吝赐教)
public static void main(String[] args) {
long y=494805L,temp = 0,ans;
while(y<=1000000007L) {
ans=y;
temp=y*2021;
temp=temp%1000000007L;
if(temp == 999999999L) {
System.out.println(ans);
break;
}
y++;
}
if(y==1000000008) {
System.out.println(y);
}
}
答案:17812964
package bluebridge;
import java.math.*;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Point []arr =new Point[450];
int num=1,x1,x2,y1,y2,a,b,c,gcdd,total=0;
Set<String> tmpSet=new HashSet<>();
String s;
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 21; j++) {
arr[num]=new Point();
arr[num].setX(i);
arr[num].setY(j);
num++;
}
}
for (int i = 1; i < num; i++) {
for (int j = 1; j < num; j++) {
//把重复的点去掉
if ((arr[i].getX()==arr[j].getX())&&(arr[i].getY()==arr[j].getY())) {
continue ;
}
x1=arr[i].getX();
x2=arr[j].getX();
y1=arr[i].getY();
y2=arr[j].getY();
a=y1-y2;
b=x2-x1;
c=x1*y2-x2*y1;
gcdd=gcd(gcd(a,b),c);
s=a/gcdd+" "+b/gcdd+" "+c/gcdd;
if(tmpSet.add(s)==true) {
total++;
}
}
}
System.out.println(total);
}
public static int gcd(int a,int b) {
return b==0?a:gcd(b, a%b);
}
}
class Point{
int x;
int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
答案:40257
思路:
- 创造一个类来表示坐标
- 使用数组将所有点存在一起
- 直线的两点式展开,分别算出a,b,c
(y1-y2) * x +(x2-x1) * y +( x1 * y2 - x2 * y1)=0,分别对应a,b,c (注意为了确定唯一性,进行约分)
- 将a,b,c拼接并存入set集合,存了多少次就说明有多少条直线
package bluebridge;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
String sn="2021041820210418",tmpString; //练习一下string转其他类型,当然也可以直接在后面加L
Long ln=Long.valueOf(sn);
long n=ln.longValue();
long tmp=(long) Math.sqrt(n);
ArrayList<Long> yinzi=new ArrayList<>(); //用来存所要求的数的因子
Set<String> anSet= new HashSet<>(); //存组合情况
for (long i = 1; i <= tmp; i++) { //求所有因子
if ((n%i)==0) {
yinzi.add(i);
yinzi.add(n/i);
}
}
for (int i = 0; i < yinzi.size(); i++) {
for (int j = 0; j < yinzi.size(); j++) {
if((yinzi.get(i)*yinzi.get(j))<=n) {
for(int k = 0; k < yinzi.size(); k++) {
if((yinzi.get(i)*yinzi.get(j)*yinzi.get(k))==n) {
tmpString=yinzi.get(i).toString()+" "
+yinzi.get(j).toString()+" "+
yinzi.get(i).toString();
anSet.add(tmpString);
}
}
}
}
}
System.out.println(anSet.size());
}
}
答案:2430
思路:
其实这题本质是因子分解,相当于求一个数可以分解为多少种由三个数组合而成的情况,把该数所有因子求出来,然后暴力组合就行了。
package bluebridge;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main {
public static void main(String[] args) {
int n,i=1,ans=1,tmp=1;
ArrayList<Integer> arr=new ArrayList<>();
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
sc.close();
arr.add(1);
while(i<n) {
i=tmp+1;
if(i>=n) {
break;
}
arr.add(i+arr.get(arr.size()-1));
tmp=tmp*3+1;
}
System.out.println(arr.size());
}
}
做题链接:
蓝桥杯2021年第十二届省赛真题-最少砝码 - C语言网 (dotcpp.com)https://www.dotcpp.com/oj/problem2612.html思路:
贪心思想:假设如果要表示的重量为2,可以用1+1,或者1+2,或者1+3来表示,那么为什么不选择能表示重量最大的那个组合呢。
找规律:
n能表示最大重量的组合最大能表示到max11121 3451 3 913141 3 9 2740.........
由上可以看出:
max=max*3+1
n=上一个max+1
每次新增的砝码的重量=n+上一个max
代码:
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
static int n;
static int x;
static ArrayList<Integer>[] arr;
public static void main(String[] args)
{
int ans;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
arr=new ArrayList[n+2];
for (int i = 1; i <= n; i++) {
arr[i]=new ArrayList<>();
}
for (int i = 2; i <= n; i++) {
x=sc.nextInt();
arr[x].add(i);
}
ans=dfs(0,1);
System.out.println(ans);
/*for (int i = 1; i <= n; i++) {
for (int j = 0; j < arr[i].size(); j++) {
System.out.print(arr[i].get(j)+"****");
}
System.out.println();
}*/
}
public static int dfs(int total,int i) {
if(arr[i].size()!=0) {
int tmpp=0,tmp=0;
for (int j = 0; j < arr[i].size(); j++) {
tmp=dfs(total, arr[i].get(j));
if(tmp>tmpp) {
tmpp=tmp;
}
}
return total+tmpp+arr[i].size();
}
else return arr[i].size();
}
}
思路:
看了好几遍题目才懂什么意思,通俗来讲就是左边可以放该节点的孩子,而右边放该节点的兄弟,所以说一个节点的右孩子的右孩子的右孩子(假设叫兄弟链)...他们全都是兄弟。从题目可以看出,要让深度最长,就要使有孩子的节点x尽量放在兄弟链的最低端,以避免它的孩子和它的兄弟平级了而浪费了一个深度。
然后可以从最简单子树开始往上长,一个一个子树的去判断,有众多兄弟的,选择以它作为根节点,高度最长的子树放在最下面,以此类推,就dfs。
未完待续...