public class Main{
public static void main(String[] args){
System.out.println(4+(20-1)+20*(22-1));
}
答案:443
方法一:蛮力算法,注意Long.MAX_VALUE为:9223372036854775807,闲着没事干儿可以用这个方法,答案约等于2e15<9e18(Long的最大值),可以循环出结果
public class Main {
public static void main(String[] args) {
long m=Long.MAX_VALUE;
for(long i=0;i<m;i++) {
if(
i%2==1&&
i%3==1&&
i%4==1&&
i%5==1&&
i%6==1&&
i%7==1&&
i%8==1&&
//此处省略
i%48==41&&
i%49==46
) {
System.out.println(i);
}else {
System.out.println("没有找到");
}
}
}
}
方法二:利用步长逐步累加
public class Main{
public static void main(String[] args) {
int[] a = {
0, 0,//为了使a[i]与i匹配,这里放入0填充a[0],a[1]
1, 2, 1, 4, 5, 4, 1, 2, 9, 0, 5, 10,
11, 14, 9, 0, 11, 18, 9, 11, 11, 15, 17, 9,
23, 20, 25, 16, 29, 27, 25, 11, 17, 4, 29, 22,
37, 23, 9, 1, 11, 11, 33, 29, 15, 5, 41, 46
};
long begin = 1;//满足题给条件的第一个模2的情况,即模2等于1的情况
long step = 1;
for (int i = 2; i < a.length - 1; i++) {
step = lcm(step, i);//每个步长本质就是前面i-1个数(除数)的最小公倍数
while (begin% (i + 1) != a[i + 1]) {
begin += step;//步长的作用就是为满足下一次模运算而逐步累加到目标值
}
}
System.out.println(begin);
}
//求最大公约数,不用考虑a,b的大小关系,可以自动调整
private static long gcd(long a, long b) {
if (b == 0) return a;
return gcd(b, a % b);
}
//求最小公倍数
private static long lcm(long a, long b) {
return (a * b)/ gcd(a, b) ;
}
}
答案:2022040920220409
import java.util.Scanner;
public class Mian {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int a[]=new int[n];
for(int i=0;i<a.length;i++) {
a[i]=sc.nextInt();
}
long s = 0;
for(int i=0;i<a.length;i++) {
for(int j=i+1;j<a.length;j++) {
s+=a[i]*a[j];
}
}
System.out.print(s);
}
}
样例答案:117
法一:
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
int b=sc.nextInt(),m;
m=Math.abs(a-b); /*假设m可被a+k,b+k整除,那么a%m=b%m,则(a-b)%m=0,要使得m最大,只需要令a-b的绝对值等于m即可。*/
System.out.print((m-a%m)%m); /*因为(a+k)%m=0,则a%m(或b%m)得到一个余数,而k值就是m-a%d,k值要保证最小,那么用k%m即可得到结果。*/
}
}
法二:
令m=|a-b|,m就是a,b的最大公约数或者是最大公约数的最大倍数,即m确定了公约数的上限,m的大小位置有两个,一个是m在(a,b)之间,另一个是m比a和b都小。
第一种情况下,k值就是m-min(a,b)
第二种情况下,找到一个最小整数n,使得m*n>a,则k=m*n-a;或者找到一个最小整数n,使得m*n>b,则k=m*n-b
import java.util.*;
public class Main {
public static void main(String args[]){
Scanner in=new Scanner(System.in);
long a,b;
long m;
a=in.nextLong();
b=in.nextLong();
m=Math.abs(a-b);
long k=0;
if(a==m||b==m) k=0;
else if(m<=a&&m<=b) {
long temp;
long t;
t=Math.max(a,b)/m+1;
k=t*m-Math.max(a, b);
}
else {
k=m-Math.min(a, b);
}
System.out.println(k);
}
}
参见:(12条消息) 第十三届蓝桥杯【蜂巢】最简单的解法_Wuxy1999的博客-CSDN博客
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n= sc.nextInt();
long num=1;
long sum=1;
long []dp=new long[n+1];
dp[0]=0;
dp[1]=0;
for (int i = 2; i <=n ; i++) {
dp[i]=(dp[i-1]*(i)+num*sum)%998244353;
sum=(sum+i)%998244353;
num=(num*i)%998244353;
}
System.out.println(dp[n]);
}
}
此处用到动态规划,数值n的全排列的价值可分为两部分,一部分是dp[n-1]*n,另外一部分是(n-1)!*(1+2+...+n-1)。
第一部分,dp[n-1]的价值假定已经确定,那么插入第n个数字的时候,每一个原排列会新产生n个新排列,那么全部新排列的价值就是dp[n-1]*n。例如,dp[4-1]的价值已经确定是9,那么插入第4个数字(也就是4),第一个原排列123会产生4123,1423,1243,1234四个新排列,而原排列一共有3!个,那么新的排列总共就有24个,但这24个排列在不考虑数字4引起的价值变化的前提下,全排列价值仅发生倍数变化,就是dp[3]*4,价值变化的原因也仅仅是排列数量的增多而已。
第二部分,我们的第一部分已经考虑了插入第n个数字后,排列增多引起的价值变化,但我们没有考虑第n个数字引起的价值变化。n-1个数字的排列有(n-1)!个,而对于每个排列,排列的间隔不会改变,数字n的插入位置有n种选择,插入数字n后,n的前面有几个数字,那么这个排列因为n的价值就是几(n在这个排列里面最大)。例如排列123,插入4,就有4123,1423,1243,1234,价值分别为0,1,2,3。所以,插入n引起的价值变化有(n-1)!*(1+2+...+n-1)。
法一:此方法思路简单,但已经超时
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
long x=0;
int n;
Scanner s=new Scanner(System.in);
n=s.nextInt();
for(int i=1;i<n+1;i++) {
x+=f(i);
}
System.out.print(x%(1e9+7));
}
private static long f(long x) {
long a=0;
for(long i=1;i<x+1;i++) {
if(x%i==0)a+=i*i;
}
return a;
}
}
法二:仅适用问题规模较小时,摘自https://blog.csdn.net/qq_46311811/article/details/124067689
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.close();
long[] arr = new long[n + 1];
long sum = 0;
for (long i = 1; i < arr.length; i++) {
long j = i;
while (j < arr.length) {
arr[(int) j] = (arr[(int) j] + i * i) % 1000000007;
j += i;
}
sum = (sum + arr[(int) i]) % 1000000007;
}
System.out.println(sum);
}
}
法三:最优算法,摘自https://blog.csdn.net/feng8403000/article/details/128891276
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
final long N = 1000000007;
final long inv6 = 166666668;
Scanner sc = new Scanner(System.in);
long res = 0, temp = 0, sum = 0;
long n, l, r, k;
n = sc.nextInt();
sc.close();
for (long i = 1; i <= n; i = r + 1) {
l = i;
k = n / i;
r = n / (n / l);
temp = sum;
sum = r * (r + (long) 1) % N * ((long) 2 * r + 1) % N * inv6 % N;
res = (res + k * (sum - temp) + N) % N;
}
System.out.println(res);
}
}
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n,k ;
n = sc.nextInt();
k = sc.nextInt();
int a[]= new int[n];
for(int i=0;i<a.length;i++) {
a[i] = sc.nextInt();
}
//Arrays.sort(a);
System.out.println(f(a,k));
}
private static long f(int b[], int k) {
int count = 0;//用于计数
int location = 0;//用于标记在数组中的位置
while(location <= b.length -k) {//按步长k移动到最后b.length%k时,可以退出循环
long min = Integer.MAX_VALUE;
int c = 0;
for(int i=location ;i<location+k;i++){//在步长k内进行循环,找到最小值
if(b[i] <= min) {
min = b[i];
c = i;//假定序列已经按升序进行排列
}
}
for(int i=location;i<location+k;i++) {
b[i]-=min;//这里的min就是连续k个数统一减小的次数
}
count+=min;
location=c+1;//记录下一次起始位置
}
for(int j=location;j<b.length;j++) {//此时只能一个数一次一次的减小
count+=b[j];
}
return count;
}
}
摘录自2022年蓝桥杯省赛java A组考后总结_java蓝桥杯a组_Hydrion-Qlz的博客-CSDN博客
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main{
static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer in = new StreamTokenizer(bf);
static int nextInt() throws IOException {
in.nextToken();
return (int) in.nval;
}
public static void main(String[] args) throws IOException {
int N = nextInt();
int M = nextInt();
int Q = nextInt();
int[][] knowArr = new int[N][N];
int[][] givenArr = new int[M][2];
for (int i = 0; i < givenArr.length; i++) {
int l = nextInt() - 1;
int r = nextInt() - 1;
int S = nextInt();
knowArr[l][r] = S;
// 以l为终点
if (l > 0) {
for (int j = 0; j < N && j < l; j++) {
if (knowArr[j][l - 1] != 0) {
knowArr[j][r] = knowArr[j][l - 1] + S;
}
}
}
// 以l为起点
if (l < N - 1) {
for (int j = l + 1; j < N; j++) {
if (knowArr[l][j] != 0) {
if (j < r) {
knowArr[j + 1][r] = S - knowArr[l][j];
} else if (j > r) {
knowArr[r + 1][j] = knowArr[l][j] - S;
}
}
}
}
// 以r为终点
if (r > 0) {
for (int j = 0; j < N && j < r; j++) {
if (knowArr[j][r] != 0) {
if (j < l) {
knowArr[j][l - 1] = knowArr[j][r] - S;
} else if (j > l) {
knowArr[l][j - 1] = S - knowArr[j][r];
}
}
}
}
// 以r为起点
if (r < N - 1) {
for (int j = r + 1; j < N; j++) {
if (knowArr[r][j] != 0) {
knowArr[l][j] = S + knowArr[r][j];
}
}
}
}
for (int i = 0; i < Q; i++) {
int l = nextInt() - 1;
int r = nextInt() - 1;
if (knowArr[l][r] != 0) {
System.out.println(knowArr[l][r]);
} else {
System.out.println("UNKNOWN");
}
}
}
}