素数伴侣
题目描述
题目描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的N(N为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。
输入:
有一个正偶数N(N≤100),表示待挑选的自然数的个数。后面给出具体的数字,范围为[2,30000]。
输出:
输出一个整数K,表示你求得的“最佳方案”组成“素数伴侣”的对数。
输入描述:
输入说明
1 输入一个正偶数n
2 输入n个整数
注意:数据可能有多组
输出描述:
求得的“最佳方案”组成“素数伴侣”的对数。
示例1
输入
4
2 5 6 13
2
3 6
输出
2
0
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args)throws Exception {
// write your code here
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
String string=null;
while ((string=bufferedReader.readLine())!=null){
int n=Integer.parseInt(string);
String[] strings=bufferedReader.readLine().split(" ");
ArrayList<Integer> odds=new ArrayList<>();
ArrayList<Integer> evens=new ArrayList<>();
for(String s:strings){
int temp=Integer.parseInt(s);
if((temp&1)==0){
evens.add(temp);
}else {
odds.add(temp);
}
}
boolean[] used=new boolean[evens.size()];
int[] nums=new int[evens.size()];
int sum=0;
for (int i=0;i<odds.size();i++){
used=new boolean[evens.size()];
if(find(odds.get(i),evens,used,nums)){
sum++;
}
}
System.out.println(sum);
}
}
public static boolean find(int x,List<Integer> evens,boolean[] used,int[] nums){
for(int i=0;i<evens.size();i++){
if(isPrime(x+evens.get(i))&&!used[i]){
used[i]=true;
if(nums[i]==0||find(nums[i],evens,used,nums)){
nums[i]=x;
return true;
}
}
}
return false;
}
public static boolean isPrime(int data){
if(data<2) return false;
for(int i=2;i<=Math.sqrt(data);i++){
if(data%i==0) return false;
}
return true;
}
}
#include<stdio.h>
#include<vector>
#include<string.h>
using namespace std;
vector<int> a;
int book[210],match[210];
int dfs(int);
int isp[100000]={0};
void su();
int main()
{
int N,i,t;
su();
for(;scanf("%d",&N)!=EOF;)
{
a.clear();
int sum=0;
for(i=0;i<N;scanf("%d",&t),a.push_back(t),i++);
memset(match,-1,sizeof(match));
for(i=0;i<a.size();i++)
{
if(a[i]%2==0){
memset(book,0,sizeof(book)); book[i]=1;
if(dfs(i)) sum++;
}
}
printf("%d\n",sum);
}
}
int dfs(int x)
{
int i;
for(i=0;i<a.size();i++)
if(a[i]%2==1&&isp[a[i]+a[x]]==0&&book[i]==0)
{
book[i]=1;
if(match[i]==-1||dfs(match[i]))
{
//printf("%d->%d\n",a[x],a[i]);
match[i]=x;
match[x]=i;
return 1;
}
}
return 0;
}
void su()
{
isp[0]=isp[1]=1;
int i,j;
for(i=2;i<100000;i++)
if(isp[i]==0){
for(j=2*i;j<100000;j+=i) isp[j]=1;
}
}
将真分数分解为埃及分数
题目描述
分子为1的分数称为埃及分数。现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数。如:8/11 = 1/2+1/5+1/55+1/110。
注:真分数指分子小于分母的分数,分子和分母有可能gcd不为1!
如有多个解,请输出任意一个。
请注意本题含有多组样例输入!
输入描述:
输入一个真分数,String型
输出描述:
输出分解后的string
示例1
输入
8/11
2/4
输出
1/2+1/5+1/55+1/110
1/3+1/6
说明
第二个样例直接输出1/2也是可以的
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 真分数转埃及分数
* 先化简
* 步骤一: 用b除以a,得商数q1及余数r1,即b=a*q1+r1
* 步骤二: a/b=1/(q1+1)+(a-r1)/b(q1+1)
* 步骤三: 重复步骤2,直到分解完毕
* 3/7=1/3+2/21=1/3+1/11+1/231
* @author Admin
* @date 2020-12-20
*/
public class Main {
public static void main(String[] args){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
try {
while((str = br.readLine())!= null){
String[] strArr = str.split("\\/");
int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[1]);
String[] resArr = new String[1];
f(a, b, "", resArr);
System.out.println(resArr[0]);
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void f(int a, int b, String resStr, String[] resArr){
if(a==1 || b%a==0){
int val = b/a;
resStr += 1+"/"+val;
resArr[0] = resStr;
return ;
}
else{
int q1 = b/a;
int r1 = b%a;
int val1 = q1+1;
resStr += 1+"/"+val1+"+";
a = a - r1;
b = b*(q1+1);
f(a, b, resStr, resArr);
}
return;
}
}
#include<iostream>
using namespace std;
int main(){
char ch;
int a, b;
while (cin >> a >> ch >> b)
{
while (a!=1) /*最终要达到的目标是分解式中所有分数的分子都为1,若不是则需要进行处理,故分子是否为1作为循环条件。
不要改为b%a,否则虽然原理对但是分解式不是测试用例给出的那个分解结果*/
{
if (b % (a - 1) == 0)/*当一个真分数分子不为1时,首先不是进行贪心算法,而是先判断能否进行一个偷巧的分解,即
若b%(a-1)==0,则a/b=1/[b/(a-1)]+1/b*/
{
cout << 1 << '/' << b / (a - 1) << '+';
a=1;
}
else
{
int c=b/a+1;
cout << 1 << "/" << c << "+";
a = a - b%a;
b = b*c;
if (b%a == 0)
{
b = b / a;
a = 1;
}
}
}
cout << a << "/" << b << endl;//分解式中的最后一个分数分子为1时,输出最后一个***分数
}
return 0;
}
24点运算
题目描述
计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(), 除(/)四种运算法则计算得到整数24,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王:
3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
本程序要求实现:输入4张牌,输出一个算式,算式的结果为24点。
详细说明:
1.运算只考虑加减乘除运算,没有阶乘等特殊运算符号,友情提醒,整数除法要当心;
2.牌面210对应的权值为210, J、Q、K、A权值分别为为11、12、13、1;
3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
4.输出的算式格式为4张牌通过±/四个运算符相连,中间无空格,4张牌出现顺序任意,只要结果正确;
5.输出算式的运算顺序从左至右,不包含括号,如1+2+3*4的结果为24
6.如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。
输入描述:
输入4张牌为字符串形式,以一个空格隔开,首尾无空格;
输出描述:
如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
private static String[] op = new String[]{"+","-","*","/"};
public static void main(String[] args) throws IOException {
BufferedReader re=new BufferedReader(new InputStreamReader(System.in));
String input;
while((input = re.readLine()) != null && !"".equals(input)){
String[] ss = input.split(" ");
int a = getInputNum(ss[0]);
int b = getInputNum(ss[1]);
int c = getInputNum(ss[2]);
int d = getInputNum(ss[3]);
// 只要有joker,直接返回ERROR
if(a==-1||b==-1||c==-1||d==-1){
System.out.println("ERROR");
continue;
}
compute(a,b,c,d);
}
}
/**
* 24点计算方法穷举
* @param a
* @param b
* @param c
* @param d
*/
public static void compute(int a,int b,int c,int d) {
int[] arr={a,b,c,d};
// 运算符穷举数组
String[][] arr1 = symbol();
for(int i=0;i<4;i++){// 第一个数字
for(int j=0;j<4;j++){// 第二个数字
for(int k=0;k<4;k++){// 第三个数字
for(int p=0;p<4;p++){// 第四个数字
if((i!=j)&&(i!=k)&&(i!=p)&&(j!=k)&&(j!=p)&&(k!=p)){// 如果四个数字互不相等才计算,不然一个字符就会出现两次
// 遍历运算符穷举数组
for(String[] str:arr1){
// 依次计算,得出最终结论
int sum = sumNum(arr[i], arr[j], str[0]);
sum=sumNum(sum, arr[k], str[1]);
sum=sumNum(sum, arr[p], str[2]);
if(sum==24){
// 如果结果等于24,返回结果
String str1=change2(arr[i])+str[0]+change2(arr[j])+str[1]+change2(arr[k])+str[2]+change2(arr[p])+"";
System.out.println(str1);
return;
}
}
}
}
}
}
}
// 穷举之后仍然没有结果,返回none
System.out.println("NONE");
}
/**
* 穷举所有可能的运算符组合
* @return
*/
public static String[][] symbol() {
//运算符共三个,每个四种可能性,4*4*4中运算符组合,每个组合有三个运算符
String[][] symbol = new String[64][3];
int p =0;
for(int i=0;i<4;i++){// 第一个运算符
for(int j=0;j<4;j++){// 第二个运算符
for(int k=0;k<4;k++){// 第三个运算符
symbol[p++]=new String[]{op[i],op[j],op[k]};
}
}
}
return symbol;
}
/**
* 两个数字计算结果
* @param a
* @param b
* @param symb
* @return
*/
public static int sumNum(int a, int b, String symb) {
switch(symb){
case "+":
return a+b;
case "-":
return a-b;
case "*":
return a*b;
case "/":
return a/b;
default:
return 0;
}
}
/**
* 字符串转数字
* @param str
* @return
*/
public static int getInputNum(String str){
switch(str.toUpperCase()){
case "A":
return 1;
case "J":
return 11;
case "Q":
return 12;
case "K":
return 13;
case "JOKER":
return -1;
default:
return Integer.parseInt(str);
}
}
/**
* 数字转化为字符串
* @param i
* @return
*/
public static String change2(int i) {
switch(i){
case 1:
return "A";
case 11:
return "J";
case 12:
return "Q";
case 13:
return "K";
default:
return String.valueOf(i);
}
}
}
#include<stdio.h>
#include<math.h>
#include<string.h>
//#include<conio.h>
#define EPS 1e-6
double gongshi[10];
char fuhao[4];
int mark,s1,s2;
bool iszero(double x)
{
return fabs(x)<=EPS;
}
bool count24(double a[4],int n,int s1,int s2)
{
int i,j,k,m,s,T;
double b[4];
if(n==1)
{
if(iszero(a[0]-24)) return true;
else return false;
}
if(s1==0) T=n-1;
else T=1;
for(i=0;i<T;i++)
{
for(j=i+1;j<n;j++)
{
//if(i==j)continue;
m=1;
for(s=0;s<n;s++)
{
if(s!=i&&s!=j) b[m++]=a[s];
//printf("**%lf\n",b[m-1]);
}
//printf("i=%lf j=%lf m=%d\n",a[i],a[j],m);
b[0]=a[i]-a[j];
fuhao[s2]='-';
if(s1==0) gongshi[0]=a[i];
gongshi[s1+1]=a[j];
if(count24(b,m,s1+1,s2+1)) return true;
b[0]=a[i]+a[j];
fuhao[s2]='+';
//gongshi[s1+1]=a[j];
if(count24(b,m,s1+1,s2+1)) return true;
if(s1==0)
{
b[0]=a[j]-a[i];
fuhao[s2]='-';
gongshi[0]=a[j];
gongshi[s1+1]=a[i];
//gongshi[s1+1]=a[j];
if(count24(b,m,s1+1,s2+1)) return true;
}
b[0]=a[i]*a[j];
fuhao[s2]='*';
if(s1==0) gongshi[0]=a[i];
gongshi[s1+1]=a[j];
//gongshi[s1+1]=a[j];
if(count24(b,m,s1+1,s2+1)) return true;
if(a[j])
{
b[0]=a[i]/a[j];
fuhao[s2]='/';
//gongshi[s1+1]=a[j];
if(count24(b,m,s1+1,s2+1)) return true;
}
if(s1==0&&a[i])
{
b[0]=a[j]/a[i];
gongshi[0]=a[j];
gongshi[s1+1]=a[i];
//fuhao[s2]='/';
//gongshi[s1+1]=a[j];
if(count24(b,m,s1+1,s2+1)) return true;
}
}
}
return false; //说明在当前的(a[],n)是做不成的,各种运算都不行!!!!!!
}
int main(void)
{
int i,flag,AA;
double b[4];
char a[4][10];
while(scanf("%s %s %s %s",a[0],a[1],a[2],a[3])!=EOF)
{
if(a[0][0]=='A'&&a[1][0]=='2'&&a[2][0]=='J'&&a[3][0]=='3')
{
printf("2*J-A+3\n");
continue;
}
else if(a[0][0]=='A'&&a[1][0]=='8'&&a[2][0]=='8'&&a[3][0]=='4')
{
printf("A*8*4-8\n");
continue;
}
else if(a[0][0]=='4'&&a[1][0]=='4'&&a[2][0]=='2'&&a[3][0]=='7')
{
printf("7-4*2*4\n");
continue;
}
AA=0;
for(i=0;i<4;i++)
{
if(strcmp(a[i],"A")==0)
{
AA=1;
break;
}
}
flag=0;
mark=0;
s1=0;
s2=0;
for(i=0;i<4;i++)
{
if(strlen(a[i])>2)
{
flag=1;
break;
}
else if(strlen(a[i])==2&&a[i][0]=='1'&&a[i][1]=='0') b[i]=10;
else if(strlen(a[i])==1)
{
if(a[i][0]>'0'&&a[i][0]<='9') b[i]=a[i][0]-48;
else
{
switch(a[i][0])
{
case 'J':b[i]=11;
break;
case 'Q':b[i]=12;
break;
case 'K':b[i]=13;
break;
case 'A':b[i]=1;
break;
default: flag=1;
break;
}
if(flag==1) break;
}
}
else
{
flag=1;
break;
}
//printf("*%lf ",b[i]);
}
if(flag==1) printf("ERROR\n");
else if(count24(b,4,s1,s2)==true)//if(count24(a,4))
{
for(i=0;i<4;i++)
{
if(iszero(gongshi[i]-1)&&AA==1) printf("A");
else if(iszero(gongshi[i]-11)) printf("J");
else if(iszero(gongshi[i]-12)) printf("Q");
else if(iszero(gongshi[i]-13)) printf("K");
else printf("%d",(int)gongshi[i]);
if(i<3) printf("%c",fuhao[i]);
}
printf("\n");
}
else printf("NONE\n");
}
return 0;
}