算法题目合集
简单循环
题目
简单斐波那契
p1
import java.util.*;
public class Main{
public static void main(String []args){
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int a=0,b=1,tmp=0;
for(int i=0;i<n;i++){
System.out.print(a+" ");
tmp=a+b;
a=b;
b=tmp;
}
in.close();
}
}
p2
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner in=new Scanner(System.in);
long f[]=new long[65];
f[0]=0;f[1]=1;
for(int i=2;i<65;i++)f[i]=f[i-1]+f[i-2];
int n=in.nextInt();
while(n-->0){
int m=in.nextInt();
System.out.println("Fib("+m+") = "+f[m]);
}
in.close();
}
}
字符串
题目
词组缩写
词组缩写
代码:
public static void main(String[] args) {
// String s=in.nextLine();
// String str[]=s.split("\\s+");
// for(int i=0;i<str.length;i++){
// if(Character.isLetter(str[i].charAt(0)))out.print(Character.toUpperCase(str[i].charAt(0)));
// }
//这段代码报超时
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String s = scanner.next();
System.out.print(Character.toUpperCase(s.charAt(0)));
}
scanner.close();
out.flush();
}
我是第几个单词
我是第几个单词
代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
String str=in.nextLine();
String key=in.next();
String str_1=str.replace(".","");
String str_2[]=str_1.split(" ");
boolean flag=false;
int l=0;
for(int i=0;i<str_2.length;i++) {
l+=str_2[i].length();
if(str_2[i].equals(key)) {
System.out.println(i+1);
flag=true;
break;
}
}
if(flag==false)System.out.println(l);
in.close();
}
}
一个六位数
一个六位数
代码:
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int i=0;
for(i=100000;;i++) {
int g=7;
int s=i/10%10;
int b=i/100%10;
int q=i/1000%10;
int w=i/10000%10;
int sw=i/100000;
int num=g*100000+sw*10000+w*1000+q*100+b*10+s;
if(num==4*i)break;
}
System.out.println(i);
}
}
java最值的应用
static int N=1010;
static int n;
static int a[]=new int[N];
public static void main(String[] args) {
n=in.nextInt();
for(int i=1;i<=n;i++)a[i]=in.nextInt();
int max=0,min=Integer.MAX_VALUE;//最值的初始化
for(int i=1;i<=n;i++){
max=Math.max(a[i],max);//得到一个数组的最大值
min=Math.min(a[i],min);//得到一个数组的最小值
}
int A_max=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j)continue;
A_max=Math.max(Math.abs(a[i]-a[j]),A_max);
}
}
out.println(max+" "+min+" "+A_max);
out.flush();
}
递归
题目
p1 跳台阶
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
int a[N];
int n;
int ans=0;
void f(int k){
if(k==n)ans++;
else if(k<n){
f(k+1);
f(k+2);
}
else return;
}
int main(){
cin>>n;
f(0);
cout<<ans<<endl;
return 0;
}
走方格-dfs
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
int a[N];
int n,m;
int ans=0;
void dfs(int x,int y){
if(x==n&&y==m)ans++;
else{
if(x<n)dfs(x+1,y);
if(y<m)dfs(x,y+1);
}
}
int main(){
cin>>n>>m;
dfs(0,0);
cout<<ans<<endl;
return 0;
}
递归实现指数型枚举
思路:
Java:
import java.util.*;
import java.io.*;
public class Main{
static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
static FastReader in=new FastReader();
static int N=16;
static int st[] = new int[N];//0表示不确定,1表示选了,2表示不选
static int n;
public static void dfs(int u){
if(u>n){
for(int i=1;i<=n;i++){
if(st[i]==1)out.print(i+" ");
}
out.println();
return;
}
st[u]=1;//当n==3时,分支成1__
dfs(u+1);//进入下一格
st[u]=0;//恢复现场,之前那一格恢复成不确定状态
st[u] = 2;//当n==3时,分支成\__
dfs(u + 1);//进入下一格
st[u]=0;//恢复现场,之前那一格恢复成不确定状态
}
public static void main(String[] args) {
n=in.nextInt();
dfs(1);
out.flush();
}
}
class FastReader{
StringTokenizer st;
BufferedReader br;
public FastReader(){
br=new BufferedReader(new InputStreamReader(System.in));
}
String next(){
while (st==null||!st.hasMoreElements()){
try {
st=new StringTokenizer(br.readLine());
}catch (IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
递归实现排列型枚举
import java.util.*;
import java.io.*;
public class Main{
static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
static FastReader in=new FastReader();
static int N=10;
static int st[]=new int[N];//储存数字
static boolean used[]=new boolean[N];//判断1-n中那些数字被使用过
static int n;
public static void dfs(int u){
if(u>n){
for(int i=1;i<=n;i++)out.print(st[i]+" ");
out.println();
return;
}
for(int i=1;i<=n;i++){//用循环从1到n遍历数字,看是否使用过,未使用的就可以储存到st[]数组中,然后递归
if(used[i]==false){
st[u]=i;
used[i]=true;
dfs(u+1);
//恢复现场
st[u]=0;
used[i]=false;
}
}
}
public static void main(String[] args) {
n=in.nextInt();
dfs(1);
out.flush();
}
}
class FastReader{
StringTokenizer st;
BufferedReader br;
public FastReader(){
br=new BufferedReader(new InputStreamReader(System.in));
}
String next(){
while (st==null||!st.hasMoreElements()){
try {
st=new StringTokenizer(br.readLine());
}catch (IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
判断质数
c++:
bool is_prime(int n){
if(n==1)return false;
int i=2;
for(i=2;i<=sqrt(n);i++){
if(n%i==0)break;
}
if(i>sqrt(n))return true;
else return false;
}
java:
public static boolean isPrime(int n) {
if(n==1)return false;
int i=2;
for(i=2;i<=Math.sqrt(n);i++) {
if(n%i==0)break;
}
if(i>Math.sqrt(n))return true;
return false;
}
快速排序
c++:
void quickSort(int a[],int l,int r){
if(l>=r)return;
int i=l-1,j=r+1,x=a[l+r>>1];
while(i<j){
while(a[++i]<x);
while(a[--j]>x);
if(i<j)swap(a[i],a[j]);
}
quickSort(a,l,j);
quickSort(a,j+1,r);
}
Java:
public static void quickSort(int[] q, int l, int r){
if(l >= r) return;
int x = q[l + r >> 1], i = l - 1, j = r + 1;
while(i < j){
while( q[++i] < x );
while( q[--j] > x) ;
if(i < j){
int t = q[i];
q[i] = q[j];
q[j] = t;
}
}
quickSort(q, l, j);
quickSort(q, j + 1, r);
}
归并排序
c++:
const int N=1e6+10;
int a[N],tmp[N];
void mergeSort(int a[],int l,int r){
if(l>=r)return;
int mid=l+r>>1;
mergeSort(a,l,mid),mergeSort(a,mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r)
if(a[i]<=a[j])tmp[k++]=a[i++];
else tmp[k++]=a[j++];
while(i<=mid)tmp[k++]=a[i++];
while(j<=r)tmp[k++]=a[j++];
for(i=l,j=0;i<=r;i++,j++)a[i]=tmp[j];
}
java:
static int N=100010;
static int tmp[]=new int[N];
public static void mergeSort(int a[],int l,int r){
if(l>=r)return;
int mid=l+r>>1;
mergeSort(a,l,mid);mergeSort(a,mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r)
if(a[i]<=a[j])tmp[k++]=a[i++];
else tmp[k++]=a[j++];
while(i<=mid)tmp[k++]=a[i++];
while(j<=r)tmp[k++]=a[j++];
for(i=l,j=0;i<=r;i++,j++)a[i]=tmp[j];
}
浮点数相除小数
public static void main(String[] args) {
DecimalFormat f=new DecimalFormat("0.000");//保留三位小数
double a=in.nextDouble();
double b=in.nextDouble();
String s=f.format((a/b));
out.print(s);
out.flush();
}
二分
知识点
1.整数二分
bool check(int x) {/* ... */} // 检查x是否满足某种性质
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
//情形1
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1注意如果下面的check函数为true时
//,是r=mid,这里就不加1;是l=mid,要加1
if (check(mid)) l = mid; // check()判断mid是否满足性质
else r = mid - 1;//同样这里如果是l,直接就记住是+1;是r,就是-1
}
return l;
}
// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
//情形2
int bsearch_2(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;//注意如果是r=mid,不加1;是l=mid,要加1
if (check(mid)) r = mid; // check()判断mid是否满足性质
else l = mid + 1;
}
return l;
}
题目
p1 数的范围
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int a[N];
int main(){
int n,q;
cin>>n>>q;
for(int i=0;i<n;i++)cin>>a[i];
while(q--){
int k;
cin>>k;
int l=0,r=n-1;
while(l<r){
int mid=l+r>>1;
if(a[mid]>=k)r=mid;
else l=mid+1;
}
if(a[l]!=k)cout<<"-1 -1"<<endl;
else {
cout<<l<<" ";
l=0,r=n-1;
while(l<r){
int mid=l+r+1>>1;
if(a[mid]<=k)l=mid;
else r=mid-1;
}
cout<<l<<endl;
}
}
return 0;
}
求阶乘
题目:求阶乘
思路:
代码:
public static long check(long n){
//求阶乘末尾0的个数其实就是 求阶乘因子中5的个数
//因为要出现10,就必须要5
//5!= 1 * 2 * 3 * 4 * 5 = 120
//10! = 1 * 2 * 3 * 4 * 5 * ... * 9 * 2 * 5 = 3628800
//15!= 1 * 2 * 3 * 4 * 5 * ... * 9 * 2 * 5 * ... * 14 * 3 * 5 = 1307674368000
long res=0;
while (n!=0){//计算一个数n含有多少个因子5
res+=n/5;
n/=5;
}
return res;
}
public static void main(String[] args) {
long k=in.nextLong();
long l=1;
long r=Long.MAX_VALUE-1;
while (l<r){
long mid=l+r>>1;
if(check(mid)>=k)r=mid;
else l=mid+1;
}
if(check(l)!=k) out.println("-1");
else out.println(l);
out.flush();
}
分巧克力
题目:分巧克力
思路:
代码:
static int n,k;
static int N=100010;
static int h[]=new int[N];
static int w[]=new int[N];
public static boolean check(int mid){
int cnt=0;
for(int i=0;i<n;i++){
cnt+=(h[i]/mid)*(w[i]/mid);//求出巧克力边长为mid时,分成的份数要大于等于K个小朋友
}
if(cnt>=k)return true;
else return false;
}
public static void main(String[] args) {
n=in.nextInt();
k=in.nextInt();
for(int i=0;i<n;i++){
h[i]=in.nextInt();
w[i]=in.nextInt();
}
int l=1,r=N;//用二分法寻找满足check函数的最大边长
while (l<r){
int mid=l+r+1>>1;
if(check(mid))l=mid;
else r=mid-1;
}
out.print(l);
out.flush();
}
跳石头
题目:跳石头
代码:
static int len,n,m;
static int a[]=new int[50005];
public static boolean check(int mid){
int last=a[0];//设置一个定距离的last
int cnt=0;
for(int i=1;i<=n;i++){
if(a[i]-last<mid){//判断相临两段距离是否大于我们设定的最小距离mid,如果比mid还小,那么这个石头就不能要
cnt++;
if(cnt>m)return false;//每次cnt++后,判断一下cnt是否大于m,大于了就说明mid不符合条件,就返回false
}
else last=a[i];//符合条件就将last往后移,进入下个循环,判断下一段距离和mid进行比较
}
return true;
}
public static void main(String[] args) {
len=in.nextInt();
n=in.nextInt();
m=in.nextInt();
for(int i=1;i<=n;i++)a[i]=in.nextInt();
int l=1,r=len;//在1-len中用二分查找最大的一个值并且要满足check函数
while (l<r){
int mid=l+r+1>>1;
if(check(mid))l=mid;
else r=mid-1;
}
out.println(l);
out.flush();
}
前缀和和差分
前缀和
一维前缀和
一维前缀和
S[i] = a[1] + a[2] + ... a[i]//前缀和的初始化
或者 for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
a[l] + ... + a[r] = S[r] - S[l - 1]//求[l,r]区间内的和
题目
前缀和
代码:
static int N=100010;
static int a[]=new int[N];
static int sum[]=new int[N];
public static void main(String[] args) {
int n=in.nextInt();
int m=in.nextInt();
for(int i=1;i<=n;i++)a[i]=in.nextInt();
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
while (m-->0){
int l=in.nextInt();
int r=in.nextInt();
out.println(sum[r]-sum[l-1]);
}
out.flush();
}
区间次方和
题目:区间次方和
代码:
static int N=100010;
static int a[]=new int[N];
static long sum[][]=new long[6][N];//这里需要求a[i]的k次方和,想到的二维数组,很巧妙
public static void main(String[] args) {
int n=in.nextInt();
int m=in.nextInt();
for(int i=1;i<=n;i++)a[i]=in.nextInt();
for(int i=1;i<=5;i++){
for(int j=1;j<=n;j++){
sum[i][j]=sum[i][j-1]+(long)Math.pow(a[j],i);
sum[i][j]%=1e9+7;
}
}
while (m-->0){
int l=in.nextInt();
int r=in.nextInt();
int k=in.nextInt();
long ans=(long)((sum[k][r]+(1e9+7)-sum[k][l-1])%(1e9+7));//这里加1e9+7是为了取极限情况:sum[k][r]被余了但是sum[k][l-1]没有,不然相减就会变成负数
out.println(ans);
}
out.flush();
}
二维前缀和
二维前缀和
S[i, j] = 第i行j列格子左上部分所有元素的和
即sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];//二维前缀和的初始化
以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]
题目
代码:
static int N=1010;
static int a[][]=new int[N][N];
static int sum[][]=new int[N][N];
public static void main(String[] args) {
int n=in.nextInt();
int m=in.nextInt();
int q=in.nextInt();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j]=in.nextInt();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];//二维前缀和的初始化
while (q-->0){
int x1=in.nextInt();
int y1=in.nextInt();
int x2=in.nextInt();
int y2=in.nextInt();
out.println(sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1]);//计算[x1,y1]到[x2,y2]之间的矩形面积和
}
out.flush();
}
差分
一维差分
首先给定一个原数组a:a[1], a[2], a[3], a[n];
然后我们构造一个数组b : b[1] ,b[2] , b[3], b[i];
使得 a[i] = b[1] + b[2 ]+ b[3] +, + b[i]
我们把b数组叫做a数组的差分数组
构造b[n] = a[n] - a[n-1]
可以在较低复杂度下计算出a数组在[l,r]区间加上一个数c
即b[l] += c;
b[r + 1] -= c;
//将序列中[l, r]之间的每个数都加上c
题目
差分
代码:
static int N=100010;
static int a[]=new int[N];
static int b[]=new int[N];
static int n,m;
public static void main(String[] args) {
n=in.nextInt();
m=in.nextInt();
for(int i=1;i<=n;i++){
a[i]=in.nextInt();
b[i]=a[i]-a[i-1]; //构建差分数组
}
while (m-->0){
int l=in.nextInt();
int r=in.nextInt();
int c=in.nextInt();
b[l]+=c;
b[r+1]-=c; //将序列中[l, r]之间的每个数都加上c
}
for(int i=1;i<=n;i++)a[i]=a[i-1]+b[i];//前缀和运算
for(int i=1;i<=n;i++)out.print(a[i]+" ");
out.flush();
}
小明的彩灯
题目:小明的彩灯
代码:
import java.text.DecimalFormat;
import java.util.*;
import java.io.*;
public class Main{
static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
static FastReader in=new FastReader();
static int N=500010;
static long a[]=new long[N];
static long b[]=new long[N];
//用到了差分数组,需要注意用Scanner会超时,数组类型用int部分答案不通过。
public static void main(String[] args) {
int n=in.nextInt();
int q=in.nextInt();
for(int i=1;i<=n;i++){
a[i]=in.nextInt();
b[i]=a[i]-a[i-1];
}
while (q-->0){
int l=in.nextInt();
int r=in.nextInt();
int x=in.nextInt();
b[l]+=x;
b[r+1]-=x;
}
for(int i=1;i<=n;i++)a[i]=a[i-1]+b[i];
for(int i=1;i<=n;i++){
if(a[i]<0){
out.print(0 + " ");
continue;
}
out.print(a[i]+" ");
}
out.flush();
}
}
class FastReader{
StringTokenizer st;
BufferedReader br;
public FastReader(){
br=new BufferedReader(new InputStreamReader(System.in));
}
String next(){
while (st==null||!st.hasMoreElements()){
try {
st=new StringTokenizer(br.readLine());
}catch (IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
二维差分
#### 题目
代码:
static int N=1010;
static int a[][]=new int[N][N];
static int b[][]=new int[N][N];
public static void insert(int x1,int y1,int x2,int y2,int c){
b[x1][y1]+=c;
b[x2+1][y1]-=c;
b[x1][y2+1]-=c;
b[x2+1][y2+1]+=c;
}
public static void main(String[] args) {
int n=in.nextInt();
int m=in.nextInt();
int q=in.nextInt();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j]=in.nextInt();
// 构建差分数组
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
b[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1];
while (q-->0){
int x1=in.nextInt();
int y1=in.nextInt();
int x2=in.nextInt();
int y2=in.nextInt();
int c=in.nextInt();
insert(x1,y1,x2,y2,c);
}
// 二维前缀和
for(int i = 1; i <= n; i++){
for (int j =1; j <= m; j++){
a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + b[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
out.print(a[i][j]+" ");
}
out.println();
}
out.flush();
}
双指针算法
题目
回文判断
代码:
public static void main(String[] args) {
String s=in.next();
int left=0,right=s.length()-1;
while (left<right){
if(s.charAt(left)!=s.charAt(right))break;
left++;
right--;
}
if(left>=right) out.println("Y");//>是判断s.length()为偶数的情况,=是判断为奇数的情况
else out.println("N");
out.flush();
}
美丽的区间
public static void main(String[] args) {
int n=in.nextInt();
int s=in.nextInt();
int a[]=new int[n];
for(int i=0;i<n;i++)a[i]=in.nextInt();
int l=0,r=0;
int sum=0;
int max_len=n+1;
while (r<n){
sum+=a[r];
while (sum>=s){
max_len=Math.min(max_len,r-l+1);
sum-=a[l];
l++;
}
r++;
}
if(max_len==n+1)out.println(0);
else out.println(max_len);
out.flush();
}
dfs
题目
p1 排列数字
#include<bits/stdc++.h>
using namespace std;
const int N=1e1+10;
int n;
int path[N];
bool st[N];
void dfs(int x){
if(x>n){
for(int i=1;i<=n;i++)cout<<path[i]<<" ";
cout<<endl;
return;
}
for(int i=1;i<=n;i++){
if(st[i]== false){
path[x]=i;
st[i]= true;
dfs(x+1);//进入下一个位置,一直递归,直到最后结束
st[i]= false;//从倒数第二个位置开始回溯,恢复现场
}
}
}
int main(){
cin>>n;
dfs(1);
return 0;
}
数的计算
题目:数的计算
思路:每递归一次就cnt++最后输出cnt就行了
代码:
static int cnt=0;
public static void dfs(int n){
if(n==0)return;
else for(int i=0;i<=n/2;i++){
dfs(i);
}
cnt++;
}
public static void main(String[] args) {
int n=in.nextInt();
dfs(n);
out.println(cnt);
out.flush();
}
红与黑
题目:红与黑
static int ans=0;
static int N=21;
static char c[][]=new char[N][N];
public static void dfs(int x,int y){
ans++;
c[x][y]='#';
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
for(int i=0;i<4;i++){
int x1=x+dx[i];
int y1=y+dy[i];
if(x1>=c.length||x1<0||y1>=c[0].length||y1<0||c[x1][y1]!='.')continue;
dfs(x1,y1);
}
}
public static void main(String[] args) {
int n=in.nextInt();
int m=in.nextInt();
//不能这样输入
// for(int i=0;i<m;i++)
// for(int j=0;j<n;j++)
// c[i][j]=in.next().charAt(0);
for(int i=0;i<m;i++)c[i]=in.next().toCharArray();
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
if(c[i][j]=='@')dfs(i,j);
out.println(ans);
out.flush();
}
模拟
题目
扫雷
public static void main(String[] args) {
int x=in.nextInt();
int y=in.nextInt();
int a[][]=new int[x][y];
for(int i=0;i<x;i++)
for(int j=0;j<y;j++)
a[i][j]=in.nextInt();
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
if(a[i][j]==1)out.print(9+" ");
else {
int cnt=0;
for(int n=i-1;n<=i+1;n++){
for(int m=j-1;m<=j+1;m++){
if(n<0||n>=x||m<0||m>=y)continue;
if(a[n][m]==1)cnt++;
}
}
out.print(cnt+" ");
}
}
out.println();
}
out.flush();
}
贪心
题目
谈判
举例n=5
1 2 3 4 5
public static void main(String[] args) {
int n=in.nextInt();
ArrayList<Integer>list=new ArrayList<>();
for(int i=0;i<n;i++)list.add(in.nextInt());
Collections.sort(list);
long sum=0;
while (list.size()!=1){
int a=list.get(0);
int b=list.get(1);
sum+=a+b;
list.remove(0);
list.remove(0);
list.add(a+b);
Collections.sort(list);
}
out.println(sum);
out.flush();
}
位运算
代码:
import java.util.*;
import java.io.*;
import java.math.*;
public class Main{
static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
static FastReader in=new FastReader();
static int N=100010;
static int n;
static int a[]=new int[N];
public static int lowbit(int x){
return x&(-x);
}
public static void main(String[] args) {
n=in.nextInt();
while (n-->0){
int res=0;
int x=in.nextInt();
while (x!=0){
x-=lowbit(x);
res++;
}
out.print(res+" ");
}
out.flush();
}
}
class FastReader{
StringTokenizer st;
BufferedReader br;
public FastReader(){
br=new BufferedReader(new InputStreamReader(System.in));
}
String next(){
while (st==null||!st.hasMoreElements()){
try {
st=new StringTokenizer(br.readLine());
}catch (IOException e){
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}