目录
P2911 [USACO08OCT] Bovine Bones G
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 这样的,纯字母/纯数字极易找错关系
有问题欢迎大家来评论区留言
我们下次见喵~