算法入门——洛谷第四章_数组(JAVA)

目录

P1428 小鱼比可爱

P1427 小鱼的数字游戏

P5727 【深基5.例3】冰雹猜想

P1047 [NOIP2005 普及组] 校门外的树

P5728 【深基5.例5】旗鼓相当的对手

P5729 【深基5.例7】工艺品制作

P2550 [AHOI2001] 彩票摇奖

P2615 [NOIP2015 提高组] 神奇的幻方

P5730 【深基5.例10】显示屏

P1554 梦中的统计

P2141 [NOIP2014 普及组] 珠心算测验

P2911 [USACO08OCT] Bovine Bones G

P1161 开灯

P5731 【深基5.习6】蛇形方阵

P5732 【深基5.习7】杨辉三角

P1789 【Mc生存】插火把

P1319 压缩技术

P1320 压缩技术(续集版)

 P1205 [USACO1.2] 方块转换 Transformations


P1428 小鱼比可爱

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc  = new Scanner(System.in);
		int n = sc.nextInt();
		int[] arr = new int[n];
		for(int i = 0;i<n;i++) {
			arr[i] = sc.nextInt();
			int b = 0;
			for(int a = 0;a<i;a++) {
				if(arr[i]>arr[a])
					b++;
			}
			System.out.printf("%d ",b);
		}
	}
}

每添加一个可爱值,就往前遍历一次,看看一共有多少个没有它”可爱“的小鱼儿~


P1427 小鱼的数字游戏

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc  = new Scanner(System.in);
		ArrayList list  = new ArrayList();
		while(true){
			int a = sc.nextInt();
			if(a == 0)
				break;
			else
				list.add(a);
		}
		for(int i = 0;i<list.size() ;i++) {
			System.out.printf("%d ",list.get(list.size() - i -1));
		}
	}
}

因为并不知道一共有多少个数,所以这里用了一个动态数组ArrayLIst

也可以读入之后用spilt方法直接进行分割


P5727 【深基5.例3】冰雹猜想

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc  = new Scanner(System.in);
		ArrayList list  = new ArrayList();
		int n = sc.nextInt();
		while(n != 1) {
			if(n %2 == 0) {
				list.add(n);
				n/=2;
			}
			else {
				list.add(n);
				n = n *3 + 1;
			}
		}
		list.add(1);
		for(int i = list.size();i>0;i--) {
			System.out.printf("%d ",list.get(i - 1));
		}
	}
}

P1047 [NOIP2005 普及组] 校门外的树

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc  = new Scanner(System.in);
		int l = sc.nextInt();
		int s = sc.nextInt();
		int[] arr = new int[l+1];
		Arrays.fill(arr,1);
		for(int i = 0;i<s;i++) {
			int min = sc.nextInt();
			int max = sc.nextInt();
			for(int a = min;a<=max;a++) {
				arr[a] = 0;
			}
		}
		Arrays.sort(arr);
		int n = 0;
		for(int i = arr.length;i>0;i--) {
			if(arr[i-1] !=  0)
				n++;
			else
				break;
		}
		System.out.println(n);
	}
}

 这个题的思路是先把所有的树都用数组表示出来,赋值为1,移走的树用0表示,最后统计剩下的1的数量,就是还剩下多少树喵~


P5728 【深基5.例5】旗鼓相当的对手

import java.util.Scanner;

public class Main {
        public static void main(String[] args) {
                Scanner sc  = new Scanner(System.in);
                int n = sc.nextInt();
                int a,b,c,sum,ans = 0;
                int[][] arr = new int[n][4];
                for(int i = 0;i<n;i++){
                        a = sc.nextInt();
                        b = sc.nextInt();
                        c = sc.nextInt();
                        sum = a+b+c;
                        int[] item = {sum,a,b,c};
                        arr[i] = item;
                }
                for(int i = 0;i<n;i++){
                        int sum1 = arr[i][0];
                        for(int m = i+1;m<n;m++){
                                int sum2 = arr[m][0];
                                if(Math.abs(sum1 -sum2)<=10){
                                        if(Math.abs(arr[i][1]-arr[m][1])<=5 &&Math.abs(arr[i][2]-arr[m][2])<=5 &&Math.abs(arr[i][3]-arr[m][3])<=5 ){
                                                ans++;
                                        }
                                }
                        }
                }
                System.out.println(ans);
        }
}

这题直接模拟即可


P5729 【深基5.例7】工艺品制作

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
        public static void main(String[] args) {
                Scanner sc  = new Scanner(System.in);
                int a,b,c,n;
                a = sc.nextInt();
                b = sc.nextInt();
                c = sc.nextInt();
                int sum = a*b*c;
                n = sc.nextInt();
                ArrayList arr = new ArrayList();
                for(int i = 0;i<n;i++){
                        int a1 = sc.nextInt();
                        int b1 = sc.nextInt();
                        int c1 = sc.nextInt();
                        int a2 = sc.nextInt();
                        int b2 = sc.nextInt();
                        int c2 = sc.nextInt();
                        for(int x = a1;x<=a2;x++){
                                for(int y = b1;y<=b2;y++){
                                        for(int z = c1;z<=c2;z++){
                                                String num = x + " " + y + " " + z;
                                                if(!arr.contains(num))
                                                        arr.add(num);
                                        }
                                }
                        }
                }
                System.out.println(sum-arr.size());
        }
}

遍历被蒸发掉的小方块的坐标,并将其记录在一个动态数组中,最后统计共有多少小方块被蒸发掉了,再用总数减去蒸发个数就是剩下的个数


P2550 [AHOI2001] 彩票摇奖

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
        public static void main(String[] args) {
                Scanner sc  = new Scanner(System.in);
                int[] ans = {0,0,0,0,0,0,0,0};
                ArrayList arr = new ArrayList();
                int n = sc.nextInt();
                for(int i = 0;i<7;i++)
                        arr.add(sc.nextInt());
                for(int i= 0;i<n;i++){
                        int s1 = 0;
                        for(int m = 0;m<7;m++){
                                if(arr.contains(sc.nextInt()))
                                        s1++;
                        }
                       ans[7-s1] += 1;
                }
                for(int i = 0;i<7;i++)
                        System.out.printf("%d ",ans[i]);
        }
}

把中奖数字存在数组内,在进行一一比对,记录下得的奖,记录在ans数组中


P2615 [NOIP2015 提高组] 神奇的幻方

import java.util.Scanner;

public class main {
        public static void main(String[] args) {
                Scanner sc = new Scanner(System.in);
                int n = sc.nextInt();
                int[][] arr = new int[n][n];
                arr[0][n/2] = 1;
                int x = 0;
                int y = n/2;
                for(int i = 2;i<=n*n;i++){
                        if(x == 0){
                                if(y != n-1){
                                        x = n-1;
                                        y = y+1;
                                }
                                else if(y == n-1)
                                        x += 1;
                        }
                        else {
                                if(y == n-1){
                                        y = 0;
                                        x -=1;
                                }
                                else{
                                        if(arr[x-1][y+1] + 1 == 1){
                                                x -=1;
                                                y +=1;
                                        }
                                        else
                                                x += 1;
                                }
                        }
                        arr[x][y] = i;
                }
                for(int i = 0;i<n;i++){
                        for(int k = 0;k<n;k++){
                                System.out.printf("%d ",arr[i][k]);
                        }
                        System.out.println();
                }
        }
}

暴力模拟,但是java中暴力模拟很容易超时,故换一种方法更好

模拟罗伯法:

我们可以看出:第一行中点开始,把每一个下面的数放到“右上角”,若右上角有数,则放到正下方。这个思路需要我们将幻方打开,拓展一下,每次出格做一个判断即可,这样可减少很多if-else的使用,具体代码如下:

import java.util.Scanner;

public class Main {
        public static void main(String[] args) {
                Scanner sc = new Scanner(System.in);
                int n = sc.nextInt();
                int[][] arr = new int[n][n];
                arr[0][n/2] = 1;
                int x = 0;
                int y = n/2;
                for(int i = 2;i<=n*n;i++) {
                        int x1 = x-1<0?n-1:x-1;
                        int y1 = y+1>n-1?0:y+1;
                        int x2 = x+1>n-1?0:x+1;
                        if(arr[x1][y1]+1==1){
                                x = x1;
                                y = y1;
                        }
                        else{
                                x = x2;
                        }
                        arr[x][y] = i;
                }
                for(int i = 0;i<n;i++){
                        for(int k = 0;k<n;k++){
                                System.out.printf("%d ",arr[i][k]);
                        }
                        System.out.println();
                }
        }
}

P5730 【深基5.例10】显示屏

import java.util.Scanner;
public class Main {
        public static void main(String[] args) {
                Scanner sc = new Scanner(System.in);
                int n = sc.nextInt();
                int a = 0;
                int b;
                String arr = sc.next();
                sc.close();
                String list =
                        "XXX...X.XXX.XXX.X.X.XXX.XXX.XXX.XXX.XXX" +
                        "X.X...X...X...X.X.X.X...X.....X.X.X.X.X" +
                        "X.X...X.XXX.XXX.XXX.XXX.XXX...X.XXX.XXX" +
                        "X.X...X.X.....X...X...X.X.X...X.X.X...X" +
                        "XXX...X.XXX.XXX...X.XXX.XXX...X.XXX.XXX";
                for(int i = 0;i<5;i++){//循环每一行
                        a = 39*i;//一行只有39个数据
                        for(int k = 0;k<n;k++){//循环每个一行
                               b = arr.charAt(k);
                               b = (b-'0')*4 + a;
                               for(int m = b;m<b+3;m++)
                                       System.out.print(list.charAt(m));
                               if(k != n-1)
                                 System.out.print(".");
                        }
                        System.out.println();
                }
        }
}

把样例中给出的示例图拿过来,一个数字占3列,所以找到对应的位置循环三次即可


P1554 梦中的统计

import java.util.Scanner;

public class Main {
        public static void main(String[] args) {
                Scanner sc = new Scanner(System.in);
                int a = sc.nextInt();
                int b = sc.nextInt();
                int[] arr = {0,0,0,0,0,0,0,0,0,0};
                for(;a<=b;a++){
                    String c = String.valueOf(a);
                    for(int i = 0;i<c.length();i++){
                        int d = c.charAt(i) - '0';
                        arr[d]++;
                    }
                }
            for(int i = 0;i<10;i++)
                System.out.printf("%d ",arr[i]);
        }
}

逐一遍历每个数,将数字记录在数组中


P2141 [NOIP2014 普及组] 珠心算测验

import java.util.*;

public class Main {
        public static void main(String[] args) {
                Scanner sc = new Scanner(System.in);
                int n = sc.nextInt();
                int ans = 0;
                ArrayList arr = new ArrayList();
                for(int i = 0;i<n;i++)
                    arr.add(sc.nextInt());
                arr.sort(Comparator.naturalOrder());
                for(int i = n-1 ;i>1;i--){
                    for(int c = 0;c<i;c++){
                        if(arr.contains(((int)arr.get(i)-(int)arr.get(c))) && arr.indexOf(((int)arr.get(i)-(int)arr.get(c)))!=c){
                            ans++;
                            break;
                        }
                    }
                }
            System.out.println(ans);
        }
}

 arr.sort(Comparator.naturalOrder()); ---对动态数组的可比较数据进行自然顺序排序

此题注意得到的数不能跟减去的数相同,即不能存在100 = 50 + 50的情况


P2911 [USACO08OCT] Bovine Bones G

import java.util.*;

public class Main {
        public static void main(String[] args) {
                Scanner sc = new Scanner(System.in);
                int a = sc.nextInt();
                int b = sc.nextInt();
                int c = sc.nextInt();
                int max = Math.max(a,Math.max(b,c));
                int min = Math.min(a,Math.min(b,c));
                int d = a+b+c-max-min;
                int ans;
                if(d<=max-min+1)
                        ans = 1+min+d;
                else
                        ans = 1+max+(d - (max - min + 1))/2 + 1;
                System.out.println(ans);
        }
}

此题公式严谨的数学推导过程在此不作过多论述,简述一下思路,这题可以先抽象为两个骰子,化做一个二维坐标系,再将它抽象为一维线段,第三个骰子的加入也将其抽象为另一段一维线段,看作是一条线段在另一条线段上的移动。

这么说我也觉得太抽象的,具体的计算过程大家有兴趣的话可以自己去探究一下,还是蛮有意思的。


P1161 开灯

import java.util.*;

public class Main {
        public static void main(String[] args) {
                Scanner sc = new Scanner(System.in);
                int n = sc.nextInt();
                boolean[] b= new boolean[2000000];
                double[] a = new double[n];
                int[] t = new int[n];
                for(int i = 0; i<n;i++){
                        a[i] = sc.nextDouble();
                        t[i] = sc.nextInt();
                        for(int k = 1;k<=t[i];k++)
                            b[(int)Math.floor(a[i]*k)] = !b[(int)Math.floor(a[i]*k)];
                }
                for(int k = 0;k<2000000;k++){
                        if(b[(int)Math.floor(k)]){
                                System.out.println(k);
                                break;
                        }
                }
        }
}

这题直接模拟就可以了,但是如果使用动态数组arraylist的话,在java中就会超时....


P5731 【深基5.习6】蛇形方阵

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int x = 0, y = 0;
        int[][] arr = new int[n][n];
        int a = 1;//当前过程序号
        arr[0][0] = 1;//设定原点/起始点
        for(int i = 2;i<=n*n;i++){//下面 || 前的条件是为了防止超范围
            if(a == 1 && (y==n-1 || arr[x][y+1] != 0)){
                a++;
            }
            else if(a == 2 && (x==n-1 || arr[x+1][y] != 0)){
                a++;
            }
            else if(a == 3 && (y==0 || arr[x][y-1] != 0)){
                a++;
            }
            else if(a==4 &&(x==0 || arr[x-1][y] != 0)){
                a = 1;
            }
            switch(a){
                case 1: y++;break;
                case 2: x++;break;
                case 3: y--;break;
                case 4: x--;break;
            }
            arr[x][y] = i;
        }
        for(int i = 0;i<n;i++){
            for(int k = 0;k<n;k++){
                System.out.printf("%3d",arr[i][k]);
            }
            System.out.println();
        }
    }
}

我感觉这题是这里面最需要说一说的题了

为便于大家理解,请大家先看下面的这张坐标图

 这个就是本题解里用到的坐标系,本题思路就是利用过程序号来控制下一个数的延伸方向,当检测到下一位会超范围或者下一位已经有数了,就不再继续当前过程,令过程序号+1,转入下一过程即可。


P5732 【深基5.习7】杨辉三角

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[][] arr = new int[n][n];
        arr[0][0] = 1;
        for(int i = 1;i<n;i++){
            for(int  k = 0;k<=i;k++){
                if(k==i || k==0)
                    arr[i][k] = 1;
                else{
                    arr[i][k] = arr[i-1][k-1]+arr[i-1][k];
                }
            }
        }
        for(int i = 0;i<n;i++){
            for(int  k = 0;k<=i;k++){
                System.out.printf("%d ",arr[i][k]);
            }
            System.out.println();
        }
    }
}

P1789 【Mc生存】插火把

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int k = sc.nextInt();
        int ans = 0;
        boolean[][] arr = new boolean[n][n];
        for(int i = 0;i<m;i++){
            int x = sc.nextInt() - 1;
            int y = sc.nextInt() - 1 ;
            for(int a = x-1;a<=x+1;a++){
                for(int b = y-1;b<=y+1;b++){
                    try{
                        arr[a][b] = true;
                    }catch (Exception e){}
                }
            }
            try{arr[x-2][y] = true;}catch (Exception e){}
            try{arr[x][y-2] = true;}catch (Exception e){}
            try{arr[x][y+2] = true;}catch (Exception e){}
            try{arr[x+2][y] = true;}catch (Exception e){}
        }
        for(int i = 0;i<k;i++){
            int x = sc.nextInt() - 1 ;
            int y = sc.nextInt() - 1;
            for(int a = x-2;a<=x+2;a++){
                for(int b = y-2;b<=y+2;b++){
                    try{
                        arr[a][b] = true;
                    }catch (Exception e){}
                }
            }
        }
        for(int i = 0;i<n;i++){
            for(int j = 0;j<n;j++){
                if(!arr[i][j])
                    ans++;
            }
        }
        System.out.println(ans);
    }
}

 try catch用于处理超范围的情况


P1319 压缩技术

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        boolean check = true;
        int num = 0;
        int sum = 0;
        while (sum != n*n){
            int b = sc.nextInt();
            sum +=b;
            for(int c =0;c<b;c++){
                if(check)
                    System.out.print(0);
                else
                    System.out.print(1);
                num++;
                if(num == n) {
                    System.out.println();
                    num = 0;
                }
            }
            check = !check;
        }
    }
}

P1320 压缩技术(续集版)

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String a;
        int n = 200,num = 0;
        int x = 0,y = 0;
        ArrayList b = new ArrayList();
       while(num != n) {
           a = sc.nextLine();
           n = a.length();
            for (int i = 0; i < n; i++) {
                int c = a.charAt(i) - '0';
                if (c == 0) {
                    x++;
                    if (y != 0) {
                        b.add(y);
                        y = 0;
                    }
                }
                else {
                    y++;
                    if (x != 0 || (num+i) ==0) {
                        b.add(x);
                        x = 0;
                    }
                }
            }
            num++;
        }
        System.out.printf("%d ",n);
        b.add(x==0?y:x);
        for(int i = 0;i<b.size();i++){
            System.out.printf("%d ",b.get(i));
        }
    }
}

 本题坑点——第一个数必须是零的个数【这里保证了num(行数)和i(字符序号)都必须为0】


 P1205 [USACO1.2] 方块转换 Transformations

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int x = 0 ,x1 = 0,ans = 7;
        boolean b1 = true;
        char[][] a = new char[n][n];
        char[][] a1 = new char[n][n];
        for(int i = 0;i<n;i++){
            String b = sc.next();
            for(int k = 0;k<n;k++) {
                a[i][k] = b.charAt(k);
                if(a[i][k] == '@')
                    x++;
            }
        }
        for(int i = 0;i<n;i++){
            String b = sc.next();
            for(int k = 0;k<n;k++) {
                a1[i][k] = b.charAt(k);
                if(a[i][k] != a1[i][k])
                    b1 = false;
                if(a1[i][k] == '@')
                    x1++;
            }
        }
        if(x != x1)
            System.out.println(7);
        else{
            ans = f1(a,a1) == 0?f2(a,a1):f1(a,a1);
            if(ans == 0 && !b1)
                System.out.println(7);
            else
                System.out.println(ans == 0?6:ans);
        }
    }
    private static int f1(char[][] a, char[][] b){
        int n = a[0].length;
        boolean b1 = true,b2 = true,b3 = true;
        char[][] c1 = new char[n][n];
        char[][] c2 = new char[n][n];
        char[][] c3 = new char[n][n];
        for(int i = 0;i<n;i++){
            for(int k = 0;k<n;k++){
                if(b1)
                    c1[i][k] = a[n-k-1][i];
                if(b2)
                    c2[i][k] = a[n-i-1][n-k-1];
                if(b3)
                    c3[i][k] = a[k][n-i-1];
                if(c1[i][k] != b[i][k])
                    b1 = false;
                if(c2[i][k] != b[i][k])
                    b2 = false;
                if(c3[i][k] != b[i][k])
                    b3 = false;
                if(!b1 && !b2 && !b3)
                    break;
            }
        }
        if(b1)
            return 1;
        else if(b2)
            return 2;
        else if(b3)
            return 3;
        else
            return 0;
    }
    private static int f2(char[][] a, char[][] b){
        int n = a[0].length;
        boolean d = true;
        char[][] c = new char[n][n];
        for(int i = 0;i<n;i++){
            for(int k = 0;k<n;k++){
                c[i][k] = a[i][n-k-1];
                if(c[i][k] != b[i][k])
                    d = false;
            }
        }
        if(d)
            return 4;
        else{
            if(f1(c,b) == 0)
                return 0;
            else
                return 5;
        }
    }
}
本题坑点就在于不好找对应关系,找对了就容易许多 画图找规律建议使用字母+数字 如a1 a2 a3 这样的,纯字母/纯数字极易找错关系

有问题欢迎大家来评论区留言

我们下次见喵~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值