记不住月份?记住这个2741数即可
转为二进制后有12位,0是小月,1是大月
第几天
2000年的1月1日,是那一年的第1天。
那么,2000年的5月4日,是那一年的第几天?
125
class MC {
int[] dm = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
boolean is29(int year){
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}
public void run() {
int cnt = 0;
int y = 2000, m = 5, d = 4;
if (is29(y)) dm[2] = 29;
for (int i = 1; i <= m - 1; i++) {
cnt += dm[i];
}
cnt += d;
System.out.println(cnt);
}
}
public class Main {
public static void main(String[] args) {
new MC().run();
}
}
方格计数
算出第一象限的小方格的数后乘4
import java.io.*;
class MC{
/**
* 题目并不仅是叫你数1x1的小方格,还有2x2,3x3,...,nxn的小方格
* 就坑人
*/
public void run() throws IOException {
long r = 1000;
long cnt = 0;
//枚举每个小方格的右下角起点(x,y)
for (int i = 1; i < r; i++) {
for (int j = 1; j < r; j++) {
if (i *i +j *j <= r *r) cnt++;
}
}
System.out.println(cnt * 4);
}
int toInt(String s){
return Integer.parseInt(s);
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
}
public class Main {
public static void main(String[] args) throws IOException {
new MC().run();
}
}
负数幂
import java.io.*;
import java.math.BigInteger;
class MC{
/**
* (a+bi)(c+di)=(ac-bd)+(bc+ad)i
*/
public void run() throws IOException {
BigInteger a = BigInteger.valueOf(2);
BigInteger b = BigInteger.valueOf(3);
BigInteger c = BigInteger.valueOf(2);
BigInteger d = BigInteger.valueOf(3);
int cnt = 123456;
for (int i = 2; i <= cnt; i++) {
BigInteger t = a;
a = a.multiply(c).subtract(b.multiply(d));
b = b.multiply(c).add(t.multiply(d));
}
if (b.compareTo(new BigInteger("0")) >= 0) System.out.printf("%s+%si", a, b);
else System.out.printf("%s%si", a, b);
}
int toInt(String s){
return Integer.parseInt(s);
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
}
public class Main {
public static void main(String[] args) throws IOException {
new MC().run();
}
}
测试次数
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;
class MC {
int N = (int) (1e4 + 10);
int n;
//f[i][j] 还有i个手机,j层待测楼的所有方案的集合中所需测试次数最小的方案
int[][] f = new int[4][N];
public void run() {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
//只有1个手机,只能一层一层试,最多试楼层的次数
for (int i = 1; i <= 3; i++) {
for (int j = 0; j <= n; j++) {
//最多试j次
f[i][j] = j;
}
}
//当前手机数
for (int i = 2; i <= 3; i++) {
//当前最大楼层数
for (int j = 1; j <= n; j++) {
//有了最大楼层数,还需知道要从哪一楼往下扔
//若手机在k层丢下去损坏,说明在[k, j]楼丢手机都一定损坏,手机数-1.搜索区间变为[1, k - 1],
//若手机在k层丢下去没有损坏,手机数不变, 说明在[1, k]楼丢手机都不会损坏,搜索区间变为[k + 1, j],测试的次数加1
for (int k = 1; k <= j; k++) {
f[i][j] = Math.min(f[i][j], Math.max(f[i - 1][(k-1) - 1 + 1], f[i][j - (k+1) + 1]) + 1);
}
}
}
System.out.println(f[3][n]);
}
}
public class Main {
public static void main(String[] args) {
new MC().run();
}
}
递增三元组
跟着大佬走
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
class MC {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = (int) (1e5 + 10);
int[] a = new int[N], b = new int[N], c = new int[N];
int n;
void handleInput(int[] t, String s){
String[] ss = s.split(" ");
for (int i = 1; i <= ss.length; i++) {
t[i] = Integer.parseInt(ss[i - 1]);
}
}
int fl(int[] h, int x){
int l = 0 , r = n + 1;
while (l < r){
int mid = l + r >> 1;
if(h[mid] >= x) r = mid; else l = mid + 1;
}
return l;
}
int fr(int[] h, int x){
int l = 0 , r = n + 1;
while (l < r){
int mid = l + r + 1>> 1;
if(h[mid] <= x) l = mid; else r = mid - 1;
}
return l;
}
public void run() throws IOException {
n = Integer.parseInt(br.readLine());
handleInput(a, br.readLine());handleInput(b, br.readLine());handleInput(c, br.readLine());
Arrays.sort(a,1,n + 1);
Arrays.sort(b,1,n + 1);
Arrays.sort(c,1,n + 1);
long res = 0;
for (int i = 1; i <= n; i++) {
int x = fl(a, b[i]);
int y = fr(c, b[i]);
if (x == 0 || y == n + 1) continue;
res += (long) (x - 1) * (n - y);
}
System.out.println(res);
}
}
public class Main {
public static void main(String[] args) throws IOException {
new MC().run();
}
}
螺旋折线
找规律+模拟
这应该可以用二分优化,以后再搞把
规律:从原点出发,向左走d,再向上走d,d+1;,向右走d,再向下走d,d+1;如此反复
因此,第p圈的各个值已经确定了,如calculate函数所示
import java.io.IOException;
import java.util.Scanner;
class MC {
/**
* 模拟:左上d+1,右下d+1
*
*/
long N = (long) (1e9 + 10);
long d = 1, x = 0, y = 0;
//从原点到(x,y)的距离
long dist = 0;
long tx, ty;
long ans;
boolean cx(){
//y相同,不管y
if (ty != y) return false;
if (Math.abs(x) < Math.abs(tx)) return false;
if (x < 0){
if(tx <= 0){
ans = dist - (tx - x);
}else ans = dist - (-x + tx);
}else {
if(tx <= 0){
ans = dist - (-tx + x);
}else ans = dist - (x - tx);
}
return true;
}
boolean cy(){
//相同,不管x
if (tx != x) return false;
if (Math.abs(y) < Math.abs(ty)) return false;
if (y < 0){
if(ty <= 0){
ans = dist - (ty - y);
}else ans = dist - (-y + ty);
}else {
if(ty <= 0){
ans = dist - (-ty + y);
}else ans = dist - (y - ty);
}
return true;
}
void calculate(long p){
long m = 2 * p;
x = p;
y = -p;
d = d + 2 * p;
dist = d * m;
// System.out.println(x + " " + y + " " + d + " " + dist);
}
boolean handle(){
//往左
x -= d;
dist += d;
if (cx()) return true;
//往上
y += d;
dist += d;
if (cy()) return true;
d++;
//往右
x += d;
dist += d;
if (cx()) return true;
//往下
y -= d;
dist += d;
if (cy()) return true;
d++;
return false;
}
public void run() throws IOException {
Scanner sc = new Scanner(System.in);
tx = sc.nextInt();
ty = sc.nextInt();
//先确定tx,ty在哪圈
calculate((Math.abs(tx)+ Math.abs(ty)) / 2);
while (!handle()){
}
System.out.println(ans);
}
}
public class Main {
public static void main(String[] args) throws IOException {
new MC().run();
}
}
日志统计
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class MC {
int N = (int) (1e5 + 10000 + 10);
int n, d, k;
int[] cnt = new int[N];
boolean[] st = new boolean[N];
int[][] logs = new int[N][2];
public void run() throws IOException {
String[] ss = br.readLine().split(" ");
n = toInt(ss[0]); d = toInt(ss[1]); k = toInt(ss[2]);
for (int i = 0; i < n; i++) {
ss = br.readLine().split(" ");
logs[i][0] = toInt(ss[0]);
logs[i][1] = toInt(ss[1]);
}
Arrays.sort(logs, 0, n, (o1, o2) -> o1[0] - o2[0]);
for (int i = 0, j = 0; i < n; i++) {
int id = logs[i][1];
cnt[id]++;
while (logs[i][0]- logs[j][0] >= d){
cnt[logs[j][1]]--;
j++;
}
if (cnt[id] >= k) st[id] = true;
}
for (int i = 0; i < N; i++) {
if (st[i]) System.out.println(i);
}
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int toInt(String s){return Integer.parseInt(s);}
}
public class Main {
public static void main(String[] args) throws IOException {
new MC().run();
}
}
全球变暖
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class MC {
int N = (int) (1e3 + 10);
int[][] g = new int[N][N];
int[][] fx = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
boolean[][] st = new boolean[N][N];
int n;
int res = 0;
public void run() throws IOException {
n = toInt(br.readLine());
for (int i = 1; i <= n; i++) {
String s = br.readLine();
for (int j = 1; j <= n; j++) {
if(s.charAt(j - 1) == '#') g[i][j] = 1;
}
}
//遍历地图
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
//如果当前不是陆地,或者已被访问过,就继续循环
if (g[i][j] == 0 || st[i][j]) continue;
//被访问过,标记一下
st[i][j] = true;
//处理以该点开始的连通块,并判断该连通块会不会沉没
handle(i, j);
}
}
System.out.println(res);
}
//找连通块并判断此联通块会不会沉没
private void handle(int i, int j) {
//bfs遍历连通块
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{i, j});
//判断该连通块会不会沉没
boolean f = true;
while (q.size() > 0){
int[] p = q.poll();
int x = p[0], y = p[1];
//该点的四周是陆地的个数
int cnt = 0;
for (int k = 0; k < 4; k++) {
int tx = x + fx[k][0], ty = y + fx[k][1];
//不用判断边界
if (g[tx][ty] == 0) continue;
//周围有块陆地
cnt++;
if (st[tx][ty]) continue;
st[tx][ty] = true;
q.add(new int[]{tx, ty});
}
//若该点周围有4块陆地,该连通块不会沉没
if (cnt == 4) f = false;
}
//若没有一个点的周围都是陆地,该连通块沉没
if(f) res++;
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int toInt(String s){return Integer.parseInt(s);}
}
public class Main {
public static void main(String[] args) throws IOException {
new MC().run();
}
}
堆的计数
在这里插入代码片