梅森素数
题目
代码
public void process() {
BigInteger num = BigInteger.valueOf(2).pow(11213).subtract(BigInteger.ONE);
String str = num+"";
String answer = str.substring(str.length()-100);
System.out.println(answer);
}
小结
-
看见这种题目臭长的,先到最后看一眼问题
-
BigInteger
类方法-
valueOf()
参数是一个long值,返回BigInteger实例
-
pow()
参数是一个int值,作为指数
-
substract()
参数是一个BigInteger实例,减法运算
可以用
BigInteger.ONE;BigInteger.TEN;BigInteger.ZERO
-
-
返回字符串str后n位
String answer = str.substring(str.length()-n);
猜年龄
题目
代码
public void process() {
for(int i = 1;i < 50;i++) {
for(int j = 1;j < 50 ;j++) {
if(i * j == (i + j) * 6 && Math.abs(i - j) <=8 && i != j) {
System.out.println(i < j ? i : j);//10
}
}
}
}
小结
- 无趣
啤酒饮料
题目
代码
public void process() {
for(int i = 1;i < 50;i++) {
for(int j = i ;j < 50;j++) {
if(Math.abs(2.3 * i + 1.9 *j - 82.3) < 0.01) {
System.out.println(i);
}
}
}
}
小结
- 避免浮点数的全等比较
- 在一定“误差”内比较,数量级小于最小的,如 2.3 --> 0.01
- 将 2.3 --> 23,扩大到整数再全等比较
武功秘籍
题目
代码
public void process() {
System.out.println(count(81, 92));
}
public int count(int a,int b) {
int n = 0;
while(a != b) {
if(a % 2 == 1) n++;
a++;
}
if(a % 2 == 0) n++;
return n;
}
小结
- 无趣
调和级数
题目
代码
public void process() {
double c = 0;
for(double i = 1.0;;i++) {
c += 1 / i;
if(c - 15.0 > 0) {
System.out.println((int)i);
break;
}
}
}
小结
- 无趣,再看见普通的遍历就不写了
李白打酒
题目
代码
public void process() {
fun(5, 10, 2);
System.out.println(count);//14
}
private int count = 0;
public void fun(int a,int b,int c) {
if(c == 1 && a == 0 && b == 1) count++;
if(a >= 0 && b >= 0 && c > 0) {
fun(a -1, b, c * 2);
fun(a, b-1, c - 1);
}
}
小结
- 比起递归返回一个值 ,我更喜欢用一个成员变量去累加,不用return
猜字母
题目
代码
public void process() {
String str = "abcdefghijklmnopqrs";
StringBuilder sb = new StringBuilder();
for(int i = 0;i < 106;i++) {
sb.append(str);
}
while(sb.length() > 1){
for(int i = 0;i < sb.length();i++) {
sb.deleteCharAt(i);
}
}
System.out.println(sb.toString());
}
小结
-
有个小坑,是 i++,而不是 i += 2
因为是针对本身删除,所以,删一个后,每个值的索引减 1,故只需 i++
扩散
题目
代码
public void process() {
int a[][] =new int[10000][10000];
Set<String> hs1 = new HashSet<>();
Set<String> hs2 = new HashSet<>();
a[5000][5000]=1; a[5000+2020][5000+11]=1;
a[5000+11][5000+14]=1; a[5000+2000][5000+2000]=1;
hs1.add("5000,5000");hs1.add("7020,5011");
hs1.add("5011,5014");hs1.add("7000,7000");
for (int i = 2; i < 2022; i++) {
for (String s : hs1) {
String[] arr = s.split(",");
int x=Integer.parseInt(arr[0]);
int y=Integer.parseInt(arr[1]);
if(a[x-1][y]==0){
a[x-1][y]=1;
hs2.add((x-1)+","+(y));
}
if(a[x][y-1]==0){
a[x][y-1]=1;
hs2.add((x)+","+(y-1));
}
if(a[x+1][y]==0){
a[x+1][y]=1;
hs2.add((x+1)+","+(y));
}
if(a[x][y+1]==0){
a[x][y+1]=1;
hs2.add((x)+","+(y+1));
}
}
hs1.clear();
hs1.addAll(hs2);
hs2.clear();
}
int count=0;
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
if(a[i][j]==1) count++;
}
}
System.out.println(count);
}
en…还有超时的解法
public void process() {
Set<Cell> set = new HashSet<>();
Set<Cell> rep = new HashSet<>();
Set<Cell> tmp = new HashSet<>();
set.add(new Cell(0, 0));set.add(new Cell(2020, 11));
set.add(new Cell(11, 14));set.add(new Cell(2000, 2000));
rep.addAll(set);
for(int i = 0;i < 2020;i++) {
for(Cell cell : rep) {
tmp.add(new Cell(cell.getX() - 1, cell.getY()));
tmp.add(new Cell(cell.getX() + 1, cell.getY()));
tmp.add(new Cell(cell.getX(), cell.getY() - 1));
tmp.add(new Cell(cell.getX(), cell.getY() + 1));
}
rep.clear();
rep.addAll(tmp);
set.addAll(tmp);
tmp.clear();
System.out.println(set.size() + "*");
}
System.out.println(set.size());
}
class Cell {
private int x;
private int y;
public Cell(int x,int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public int hashCode() {
return x * 10 + y;
}
@Override
public boolean equals(Object other) {
if(other == this) return true;
if(!(other instanceof Cell)) return false;
Cell o = (Cell)other;
return o.x == x && o.y == y;
}
}
小结
-
在层层扩展中,有用到两个序列,
一个序列用来存储每次待处理的节点,接受遍历
另一个序列存储每次扩展出来的节点
然后来回倒值,使得每次都处理新扩展的节点
-
我好想用Hash的去重机制做啊
在分钟少的情况下,还能出结果,
但在2020分钟的情况下,却因为要存储千百万个对象而耗时太久
三升序列
题目
代码
char[][] chs = new char[30][50];
int[][] dir = { { 0, 1 }, { 1, 0 }, { 1, 1 }, { 1, -1 }, { -1, 1 } };
int cnt = 0;
public void init() {
try {
BufferedReader in = new BufferedReader(new FileReader("src/March/threeIncrease.txt"));
String str;
int row = 0;
while ((str = in.readLine()) != null) {
chs[row++] = str.toCharArray();
}
} catch (Exception e) {}
}
@Override
public void process() {
init();
int ia, ib, iaa, ibb;
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 50; j++) {
for (int k = 0; k < 5; k++) {
ia = i;
ib = j;
while (true) {
ia += dir[k][0];
ib += dir[k][1];
iaa = ia;
ibb = ib;
if (ia < 0 || ib < 0 || ia >= 30 || ib >= 50) {
break;
}
while (true) {
iaa += dir[k][0];
ibb += dir[k][1];
if (iaa < 0 || ibb < 0 || iaa >= 30 || ibb >= 50) {
break;
}
if (chs[i][j] < chs[ia][ib] && chs[ia][ib] < chs[iaa][ibb]) {
cnt++;
}
}
}
}
}
}
System.out.println(cnt);
}
小结
- 题意不好读,琢磨好方向,得出
int[][] dir
- 三个值的选择实现
char[i][j]
通过两个for循环实现char[ia][ij]
在char[i][j]
确定的基础上,循环5个方向,逐渐累加步长实现char[iaa][ibb]
在char[ia][ib]
确定的基础上,仍沿其方向,逐渐累加步长实现- 直到越界,跳出循环
寻找2020
题目
代码
char[][] chs;
public void init() {
ArrayList<String> list = new ArrayList<>();
try {
BufferedReader in = new BufferedReader(new FileReader("src/March/2020.txt"));
String str;
while((str = in.readLine()) != null) {
list.add(str);
}
in.close();
} catch (Exception e) {}
chs = new char[list.size()][list.get(0).length()];
int i = 0;
for(String str : list) {
chs[i++] = str.toCharArray();
}
}
@Override
public void process() {
init();
int row = chs.length;
int column = chs[0].length;
int cnt = 0;
for(int i = 0;i < row;i++) {
for(int j = 0;j < column;j++) {
if(j + 3 < column &&
chs[i][j] == '2' &&
chs[i][j + 1] == '0' &&
chs[i][j + 2] == '2' &&
chs[i][j + 3] == '0')
cnt++;
if(i + 3 < row &&
chs[i][j] == '2' &&
chs[i + 1][j] == '0' &&
chs[i + 2][j] == '2' &&
chs[i + 3][j] == '0')
cnt++;
if(i + 3 < row && j + 3 < column &&
chs[i][j] == '2' &&
chs[i + 1][j + 1] == '0' &&
chs[i + 2][j + 2] == '2' &&
chs[i + 3][j + 3] == '0')
cnt++;
}
}
System.out.println(cnt);
}
小结
- 此题是三升序列的的弟弟
- 处理文件,确定二维数组的大小处可供参考