算法训练#20:单纯的模拟

80 阅读1分钟

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天,点击查看活动详情

第一题

Infinity Table

题目理解

给出一个矩阵,该矩阵中存在着一系列按照规律排列的自然数,规律如下所示

1251017
4361118
9871219
1615141320
2524232221

要求我们找到任意一个自然数在该矩阵中的位置

输入

输入整数tt,代表案例个数,1t1001\le t\le 100
每个案例第一行输入1个整数kk1k1091\le k\le 10^{9}

输出

每个案例输出22个整数——代表kk在矩阵中的下标

思路

对于这道题,我唯一能找到的规律就是:这些数字,是逐层包裹住的。也就是说,我们可以去尝试判断出要找的数在哪一层,然后再去具体寻找它在哪里。若找到层数了,我们可以知道在这一层中,数是逐列递减,逐行递增的,那么利用好这个规律,就可以简单的找出整数的所在位置了。

代码

import java.util.Scanner;

public class infinity_table {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        for (int i = 0; i < t; i++) {
            int find = sc.nextInt();
            int flag = 1;
            while(find>flag*flag){
                flag++;
            }
            int row=flag;
            int col=1;
            int big=flag*flag;
            while(big>find){
                big--;
                if(col<flag)
                    col++;
                else
                    row--;
            }
            System.out.println(row+" "+col);
        }
    }
}

第二题

Simply Strange Sort

题目理解

给出一个长度为奇数的数组(下文统一称长度为n),里面存取着1至n的自然数,然后下面对数组进行如下操作:若数组第a项大于第a+1项,则交换它们的值。

  1. 在i为奇数时,第i次操作会把偶数下标的值作为上述第a项的判定(下标n-1除外)
  2. 在i为偶数时,第i次操作会把奇数下标的值作为上述第a项的判定

求出在哪一次数组可以变成升序排列

输入

输入整数tt,代表案例个数,1t1001\le t\le 100
每个案例第一行输入1个整数nn3n999,且n是奇数3\le n\le 999,且n是奇数 每个案例第一行输入nn个整数nn

输出

每个案例输出11个整数——代表最少需要的步数

思路

思路比较简单,就是把题目中的情况模拟下来,但是模拟时有一些需要注意的东西,我们看代码

代码

import java.util.Scanner;

public class jio {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        for(int i=0;i<t;i++){
            int n=sc.nextInt();
            int[] a=new int[n];
            for(int i1=0;i1<n;i1++){
                a[i1]=sc.nextInt();
            }
            int count=0;//存放答案
            int fcount=0;//实时计算
            boolean d=true;//检验是否为升序数组
            boolean c=false;//检验是否需要或者发生了交换操作
            while(d){
                d=false;
                //把题目的意思转化成代码
                for(int i1=fcount%2;i1<n-1;i1+=2){
                    if(a[i1]>a[i1+1]){
                        int temp=a[i1];
                        a[i1]=a[i1+1];
                        a[i1+1]=temp;
                        c=true;
                    }
                }
                fcount++;
                if(c) {
                    count=fcount;
                }
                //判断是否完全升序
                for (int j=0;j<n-1;j++) {
                    if(a[j]>a[j+1]){
                        d=true;
                        break;
                    }
                }
            }
            System.out.println(count);
        }
    }
}