后面3题参考大佬…
1.求n个数最多可以分为多少个素数
package wangyiyun;
import java.util.Scanner;
/**
* @author liu
* @Description
*/
public class main1 {
public static void main(String[] args) {
// Scanner sc = new Scanner(System.in);
// int n = sc.nextInt();
//
// int sum=0;
// int[] a = new int[n];
// for(int i =0;i<n;i++ ){
// a[i] = sc.nextInt();
// sum += a[i]/2;
// }
//
// System.out.println(sum);
Scanner sc = new Scanner(System.in);
long l = sc.nextLong();
long sum=0;
long lg;
for(long i =0;i<l;i++ ){
lg = sc.nextLong();
sum += lg/2;
}
System.out.print(sum);
}
}
- 参考:https://blog.csdn.net/qq_33241802/article/details/107884289
- 参考:https://blog.csdn.net/hjd_love_zzt/article/details/14525117
3.n个含有不同价值的物品,分给两个人,要求两人得到的价值是相同的,多余的物品丢掉,求最少需要丢掉多少价值可以使得两人的价值相等。
输入:
第一行T:测试T组数据
接下来每组数据:
第一行n:代表物品个数
第二行n个数:表示n个物品格自的价值
输入:
1
5
60 30 15 5 30
输出:
20 (每人平均分60价值)
static int res;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
while(t-->0){
res = Integer.MAX_VALUE;
int n = scan.nextInt();
int[] item = new int[n];
for(int i =0;i<n;i++)
item[i] = scan.nextInt();
a3(item, 0,0,0, 0);
System.out.println(res);
}
}
public static void a3(int[] item,int index,int x,int y,int r){
if(index == item.length){
if(x == y)
res = Math.min(r,res);
return;
}
a3(item,index+1,x+item[index],y,r)
a3(item,index+1,x,y+item[index],r);
a3(item,index+1,x,y,r+item[index]);
}
4.求n个节点,m个边的无向图中,选取n-1条边,构成二叉树连接所有节点,说出权重最大边和权重最小边的差值最小是多少。
输入:
3 5 (3个节点、5条边)
1 2 10 (节点1、节点2、权重为10)
1 3 5
3 1 12
2 3 19
1 2 74
输出:
2 (选取第一个和第三个,12-10=2)
/*
* POJ_2421.cpp
*
* Created on: 2013年11月8日
* Author: Administrator
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
struct edge{
int begin;
int end;
int weight;
};
const int maxn = 110;
int father[maxn];
edge e[maxn*maxn];
int map[maxn][maxn];
int n,m;
int find(int x){
if( x == father[x]){
return x;
}
father[x] = find(father[x]);
return father[x];
}
int kruscal(int start){//使用kruscal算法来生成最小生成树并计算带权路径和
int i;
int sum = 0;//用sum来记录最小s生成树的边权和
int max = INT_MIN;
int min = INT_MAX;
int count = 0;
for( i = 1 ; i < maxn ; ++i){
father[i] = i;
}
for( i = start ; i <= m ; ++i){//枚举有序边集中的每一条边
int fx = find(e[i].begin);
int fy = find(e[i].end);
if(fx != fy){//若第k条边的两个端点i,j 分别属于两颗不同的子树
father[fx] = fy;//则将节点i所在的子树并入节点j所在的子树中
sum += e[i].weight;
//求解每种生成树的(max - min)值
count++;
if(e[i].weight > max){
max = e[i].weight;
}
if(e[i].weight < min){
min = e[i].weight;
}
}
}
if(count != n-1){//不是生成树
return -1;
}
return max - min;
}
bool compare(const edge& a , const edge& b){
return a.weight < b.weight;
}
//以上是用kruscal算法来解决问题的基本模板.....
int main(){
while(scanf("%d%d",&n,&m)!=EOF,n||m){
int i,j;
for(i = 1 ; i <= m ; ++i){
scanf("%d%d%d",&e[i].begin,&e[i].end,&e[i].weight);
}
sort(e+1,e+m+1,compare);//kruscal算法要求边有序..特别需要注意的是排序的起点和终点
/**
*
* 求生成树中最大边权值和最小边权值之差最小的:
* 枚举每一条边,将其作为下界,向右寻找一个上界...
* 使得生成树的最大边权值-最小边权值的差最小
*
*/
int slim = INT_MAX;
slim = min(slim,kruscal(1));
if(slim != -1){
for(i = 2 ; i <= m ; ++i){
int temp = kruscal(i);
if(temp >= 0){
slim = min(slim,temp);
}
}
}
printf("%d\n",slim);
}
return 0;
}
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int m = scan.nextInt();
int[] s = new int[m];
for(int i=0;i<m;i++){
s[i] = scan.nextInt();
}
int[] t =a(s,n);
for(int i=0;i<t.length-1;i++){
System.out.print(t[i]);
System.out.print(" ");
}
System.out.print(t[n-1]);
System.out.print("\n");
}
public static int[] a(int[] s,int n){
int[] t = new int[n];
int m = s.length;
int[] tmp = new int[n-m];
HashSet<Integer> set = new HashSet<>();
for(int i:s){
set.add(i);
}
int index=1;
for(int i=0;i<tmp.length;i++){
while(set.contains(index))
index++;
tmp[i] = index++;
}
int index1 = 0;
int index2 = 0;
for(int i=0;i<t.length;i++){
if(index1 <m && index2<n-m){
if(s[index1] <= tmp[index2]){
t[i] = s[index1++];
}else{
t[i] = tmp[index2++];
}
}else if(index1<m){
t[i] = s[index1++];
}else{
t[i] = tmp[index2++];
}
}
return t;
}