平方矩阵Ⅱ
输入整数 N,输出一个 N 阶的二维数组,数组的形式参照样例。
输入格式
输入包含多行,每行包含一个整数 N。
当输入行为 N=0 时,表示输入结束,且该行无需作任何处理。
输出格式
对于每个输入整数 N,输出一个满足要求的 N阶二维数组。
每个数组占 N 行,每行包含 N 个用空格隔开的整数。
每个数组输出完毕后,输出一个空行。
数据范围
0≤N≤100
输入样例:
1 2 3
输出样例:
1 1 2 2 4 1 2 4 2 4 8 4 8 16
思路:观察输出矩阵的特点,
方法一:矩阵规律是沿着对角线分别向右侧和下侧增加,找到对角线上一值,分别向右和下逐增至n即可编辑
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
int[][] arr = new int[110][110]; //0<N<100
while(scanner.hasNextInt()){
int n =scanner.nextInt();
for(int i =0 ;i <= n ;i++){
for(int j = i,k =1;j<=n;j++,k++){
arr[i][j] = k;
arr[j][i] = k;
}
}
// 输出
for(int i = 1;i <= n ;i ++){
for(int j = 1;j <= n ;j ++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
}
方法二:找特殊规律,i - j 的绝对值+1的值,即为对应(i , j)坐标下的元素值
编辑
import java.util.Scanner;
import java.lang.Math.abs;
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextInt()){
int n =scanner.nextInt();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n ; j++) {
System.out.print(abs(i-j)+1+" ");
}
System.out.println();
}
System.out.println();
}
}
}
平方矩阵Ⅲ
输入整数 N,输出一个 N 阶的二维数组 M。
这个 NN 阶二维数组满足 Mi=2 ^i+j
具体形式可参考样例。
输入格式
输入包含多行,每行包含一个整数 N。
当输入行为 N=0时,表示输入结束,且该行无需作任何处理。
输出格式
对于每个输入整数 N,输出一个满足要求的 NN 阶二维数组。
每个数组占 N行,每行包含 N 个用空格隔开的整数。
每个数组输出完毕后,输出一个空行。
数据范围
0≤N≤15
输入样例:
1 2 3 0
输出样例:
1 1 2 2 4 1 2 4 2 4 8 4 8 16
思路:利用for循环,输出pow(2,i+j)即可,注意换行和空格
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int n = sc.nextInt();
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
int res = (int)Math.pow(2,i+j);
System.out.printf(res+" ");
}
System.out.println();
}
System.out.println();
}
}
}
题目一:
CD145 整数的二进制数表达中有多少个1
给定一个整数n,返回该整数二进制形式1的个数。
方法一:将三十二位二进制数字分别与1的二进制形式相与,由 0 & 1 = 0 1 & 1 = 1
思路:将该数字的每一位与32位的1相与,使用移位运算每次移动一位二进制数字如:
n = 0011 0010 & 0000 0001 count = 0 n>>1
n = 0001 1001 & 0000 0001 count = 1 n>>1
以此类推
public static void main2(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int count = 0;
for (int i = 0; i < 32; i++) {
if (((n >> i) & 1) != 0) {
count++;
}
}
System.out.println(count);
}
缺陷:每个数都要按位与完32位,存在重复比较的情况,增加一个判断条件即可
/**
* 移动的过程中判断 n 是否为 0
* 无循环判断32次,所以使用无符号右移
* @param args
*/
public static void main5(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int count = 0;
while(n!=0){
if((n&1) != 0){
count++;
}
n = n >>> 1;
}
System.out.println(count);
}
}
此种情况下,避免了移动一定位数后n的左侧全为0的情况
方法二:
思路:相邻的两个数按位与运算,每相与一次即减少一个一,得到的即为大数中1的个数10= 0000 1010 & 9 = 0000 1001 --> 0000 1000 count =1
0000 1000 & 0000 0111 = 0000 0000 count = 2
/**
* n与n-1相与,每相与一次即少一个一,次数即n中1的个数
*/
public static void main4(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int count = 0;
while (n != 0) {
n = n&(n-1);
count++;
}
System.out.println(count);
}
题目二:
模拟登录
编写代码模拟三次密码输入的场景。 最多能输入三次密码,密码正确,提示“登录成功”,密码错误, 可以重新输 入,最多输入三次。三次均错,则提示退出程序
public static void main(String[] args) {
Scanner s =new Scanner(System.in);
int count = 3;
while(count != 0){
System.out.println("请输入你的密码,还有"+count+"次机会");
String pass = s.nextLine();
if(pass.equals("123")) {
System.out.println("登录成功");
break;
}else{
System.out.println("登录失败");
count--;
}
}
}
题目三:
二进制序列
获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列
思路:提取所有的奇数位和偶数位,分别与1相与,结果为1则1,为0则0
/**
* 获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列
*/
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n =s .nextInt();
for (int i = 31; i >= 1 ; i-=2) {
System.out.print(((n>>i)&1)+" ");
}
System.out.println();
for (int i = 30; i >= 0 ; i-=2) {
System.out.print(((n>>i)&1)+" ");
}
}
题目四
奇数位于偶数之前
调整数组顺序使得奇数位于偶数之前。调整之后,不关心大小顺序。如数组:[1,2,3,4,5,6],调整后可能是:[1, 5, 3, 4, 2, 6]
思路:保持 i < j 判断奇偶,交换位置,使奇数位于偶数之前
public static void func2(int[] array){
int i= 0;
int j =array.length-1;
while(i<j){
while(i<j && array[i] % 2 != 0){
i++;
}
while(i<j && array[j] %2 == 0){
j--;
}
int tmp = array[i];
array[i] = array[j];
array[j] =tmp;
}
}
题目五
两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
思路:暴力解法,使用双层循环解题
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] nums2 =new int[2];
for (int i = 0; i < nums.length; i++) {
for (int j = i+1; j < nums.length && j!=i ; j++) {
if (nums[i] + nums[j] == target) {
nums2[0]=i;
nums2[1]=j;
}
}
}
return nums2;
}
}