排他平方数
题目链接:https://www.lanqiao.cn/problems/712/learning/
这里有一个地方需要注意的是,使用long的时候要显示转换一下,或者写成
222L
这种形式,不然像19行那里会直接变成负数,具体原因与数字在计算机中的编码格式有关,有兴趣可自己了解一下然后在这种题里面应该掌握的就是哈希集合去查找元素,使用普通列表查找元素的时间复杂度为O(n),但是对于哈希集合来说只有O(1),哈希表也是类似的
package daily;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 题目链接:https://www.lanqiao.cn/problems/712/learning/
*
* @author Jia
*
*/
public class day3_9_1 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
// 因为要求每个数位上位置不能相同,所以直接省略前面和后面有相同数字的
for (int i = 123456; i <= 987654; i++) {
long mult = (long) i * i;
// 这里判断是不是6位数都不相同,如果有相同的则哈希集合大小小于6
Set<Integer> set = getSet(i);
if (set.size() != 6) {
continue;
}
// 这里判断是否有重复的数字,也是用哈希集合判断,对于查找老说O(1)时间非常好用
while (mult > 0) {
if (set.contains((int) (mult % 10))) {
break;
}
mult = mult / 10;
}
if (mult == 0) {
list.add(i);
}
}
// System.out.println(list); 这里可以看总共有几个数字,由于提交时不能有多余输出就注释了
for (int i = 0; i < list.size(); i++) {
if (list.get(i) != 203879) {
System.out.println(list.get(i));
}
}
}
/**
* 将传入的数组按位转换为一个哈希集合
*
* @param i
* @return
*/
private static Set<Integer> getSet(int i) {
Set<Integer> set = new HashSet<>();
while (i > 0) {
set.add(i % 10);
i /= 10;
}
return set;
}
}
买不到的数目
题目链接:https://www.lanqiao.cn/problems/213/learning/
这个题是一个典型的动态规划问题,如果这个数减去n或者减去m可以拼出来,那么这个数一定可以拼出来,用这个作为dp的递推式就可以很容易做出来,dp一般用得都是数组去记录情况的,这里我是看到题目中输入的范围在0-1000,如果用数组会浪费部分空间,所以直接使用哈希集合了,如果使用数组的话需要判断的是
arr[i]==true
package daily;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class day3_9_2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
sc.close();
Set<Integer> set = new HashSet<>();
int max = 0;
set.add(m);
set.add(n);
for (int i = 0; i < m * n; i++) {
// 判断减去m或n是否可以拼出来,如果可以的话则这个数肯定可以拼出来
if (set.contains(i - n) || set.contains(i - m)) {
set.add(i);
} else {
max = i;
}
}
System.out.println(max);
}
}
回文日期
题目链接:https://www.lanqiao.cn/problems/498/learning/
在这个题里面,如果自己处理合法的数字的话需要考虑每个月有多少天,直接使用日历类去得到遍历的对象,然后自己格式化一下就可以得到合法的数字了
另外,我觉得如果直接判断是不是回文数或者是不是ABAB型的有点难,于是我就采用构造它的回文数与它的ABAB型回文数,然后判断是不是与原数字相同,这种比直接判断应该能简单一点
package daily;
import java.util.Calendar;
import java.util.Scanner;
public class day3_9_3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
sc.close();
int normal = 0;
int ababType = 0;
// 设置初始日期,按照格式取数字就了
Calendar c = Calendar.getInstance();
c.clear();
c.set(Calendar.YEAR, N / 10000);
c.set(Calendar.MONTH, (N % 10000 / 100) - 1);
c.set(Calendar.DAY_OF_MONTH, N % 100);
for (int i = N + 1; i < 99999999; i++) {
// 每次循环加一天
c.add(Calendar.DAY_OF_MONTH, 1);
// 得到这一天的格式化日期
int date = c.get(Calendar.YEAR) * 10000 + (c.get(Calendar.MONTH) + 1) * 100 + c.get(Calendar.DAY_OF_MONTH);
// 在这里判断是不是回文数
int rev = reverse(date);
// 如果翻转后的数字与原数字相同,则就是回文数
if (rev == date) {
if (isABAB(date)) {
// 这里表示当前数字是ABAB型的
ababType = date;
break;
}
if (normal == 0) {
normal = date;
}
}
}
if (normal == 0) {
System.out.println(ababType);
System.out.println(ababType);
} else {
System.out.println(normal);
System.out.println(ababType);
}
}
/**
* 这里根据ABAB型回文数构造数字,判断与原数字是否相同
*
* @param i
* @return
*/
private static boolean isABAB(int i) {
int A = i % 10;
int B = (i % 100) / 10;
int[] nums = { A, B, A, B, B, A, B, A };
int sum = 0;
for (int j = 0; j < nums.length; j++) {
sum = sum * 10 + nums[j];
}
return sum == i;
}
/**
* 这里翻转原数字,判断与数字是否相同
*
* @param i
* @return
*/
private static int reverse(int i) {
int ret = 0;
while (i > 0) {
ret = ret * 10 + i % 10;
i = i / 10;
}
return ret;
}
}
约瑟夫环
题目链接: https://www.lanqiao.cn/problems/231/learning/
这个题我没做出来,正常做法直接超时了,挺懵逼的,然后在网上找到了递推的方法,反正我没看懂…后面再琢磨琢磨
package daily;
import java.util.Scanner;
public class day3_9_4_ac {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
sc.close();
int res = 0;
for (int i = 2; i <= n; i++) {
res = (res + k) % i;
}
System.out.print(res + 1);
}
}
下面是我超时的做法,希望大佬可以说说怎么改进
package daily;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class day3_9_4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
sc.close();
int count = n;// 当前剩余人数
List<Integer> indexArray = new ArrayList<>();
for (int i = 0; i < n; i++) {
indexArray.add(i);
}
int index = 0;
while (count > 1) {
// 当前指向的人是第一个,所以只需要向后面数k-1个
index = (index + k - 1) % indexArray.size();
indexArray.remove(index);
count--;
}
// 输出结果
System.out.println(indexArray.get(0) + 1);
}
}