java趣味编程100实例doc.docx
《java趣味编程100实例doc.docx》由会员分享,可在线阅读,更多相关《java趣味编程100实例doc.docx(26页珍藏版)》请在冰豆网上搜索。
java趣味编程100实例doc
1_1
问题描述:
根据福利彩票的规则,6个蓝色球,范围1--32,不允许重复,1个红色球,范围1-16,自动生存6个蓝色球,1个红色球。
importjava.util.Arrays;
importjava.util.Random;
importjava.util.Scanner;
publicclassCh11_2
{
/**
*根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组
*@parambegin最小数字(包含该数)
*@paramend最大数字(不包含该数)
*@paramsize指定产生随机数的个数
*
*实现思路:
首先定义一个方法,使它能够产生6个不重复的蓝色随机数,存放到数组中,
*再产生1个红色随机数,最后他们组合在一起就是题目所求
*/
publicstaticint[]generateRandomNumber(intbegin,intend,intsize)
{
//加入逻辑判断,确保beginif(begin>=end||(end-begin){
returnnull;
}
//种子你可以随意生成,但不能重复里面存放的是你的取值范围
//本题就是[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]
int[]seed=newint[end-begin];
for(inti=begin;i{
seed[i-begin]=i;
}
int[]ranArr=newint[size];
Randomran=newRandom();
//数量你可以自己定义。
这里生成了6个蓝色球的号码
for(inti=0;i{
//得到一个位置
intj=ran.nextInt(seed.length-i);
//得到那个位置的数值
ranArr[i]=seed[j];
//将最后一个未用的数字放到这里,这样就把取出的数覆盖了,达到了不重复的目的。
seed[j]=seed[seed.length-1-i];
}
returnranArr;
}
publicstaticvoidmain(String[]args)
{
int[]ranArr={};
intred;
Scannerinput=newScanner(System.in);
Randomran=newRandom();
System.out.println("欢迎使用双色球自动摇号系统");
System.out.print("确实摇号(y/n)?
");
Stringgo;
go=input.next();
while(go.equalsIgnoreCase("y"))
{
ranArr=generateRandomNumber(1,33,6);
red=ran.nextInt(16);
System.out.println(Arrays.toString(ranArr)+""+red);
System.out.print("继续摇号(y/n)?
");
go=input.next();
}
System.out.println("谢谢使用!
");
}
}
1_2超长整数的相加
问题描述:
编写程序,实现超过整形变量存储范围数据的相加
importjava.util.Arrays;
importjava.util.Scanner;
publicclassCh11_4
{
/**
*实现思路:
1将两个超长的整形转换为字符串
*2将两个字符串变为等长,如:
30812111123298----3081211112300000000289
*3将两个字符串对应相加,结果存到到另一个字符串
*4最后对新的字符串做进位处理
*@paramargs
*/
publicstaticvoidmain(String[]args)
{
//Scannerinput=newScanner(System.in);
//System.out.print("请输入第一个加数:
");
//StringaddA=input.next();
//System.out.print("请输入第二个加数:
");
//StringaddB=input.next();
StringaddA="30812111123";
StringaddB="298";
//调用方法计算结果,输出
System.out.println(addA+"+"+addB+"="+strvalue(addA,addB));
}
/**
*将两个字符串相加,得到新的字符串
*/
publicstaticStringstrvalue(StringaddA,StringaddB)
{
Stringstrvalue="";
intlenA=addA.length();
intlenB=addB.length();
inttemplen=0;
//调整长度相同
if(lenA>=lenB)
{
templen=lenA-lenB;
addB=maxlen(addB,templen);//调整长度,使其跟大数长度一致
}else{
templen=lenB-lenA;
addA=maxlen(addA,templen);
}
charaddcharA[]=addA.toCharArray();
charaddcharB[]=addB.toCharArray();
intlen=addcharA.length;
intvalueC[]=newint[len];
for(inti=0;i{
//取出字符串中的数转换为数字
inta=Integer.parseInt(String.valueOf(addcharA[i]));
intb=Integer.parseInt(String.valueOf(addcharB[i]));
valueC[i]=a+b;//每项相加存储
}
System.out.println(Arrays.toString(valueC));
inttmp=0;//代表进位
//处理进位从个位开始
for(inti=valueC.length-1;i>=0;i--)
{
if(valueC[i]>=10)
{
strvalue=String.valueOf(valueC[i]+tmp-10)+strvalue;
tmp=valueC[i]/10;
}else{
strvalue=String.valueOf(valueC[i]+tmp)+strvalue;
tmp=0;
}
}
returnstrvalue;
}
//调整长度,使其长度一样
privatestaticStringmaxlen(Stringstr,inttemplen)
{
Stringstrmax=null;
StringBufferbuff=newStringBuffer();
for(inti=0;i{
buff.append("0");
}
strmax=buff.toString()+str;
returnstrmax;
}
}
1_3尾数前移
问题描述:
求一个自然数N,个位数是6,将6提到最前面得到的数是N的4倍
publicclassCh11_5
{
/**
*问题分析:
1假设这个数是n6(n是从1开始的正整数)
*2满足关系6n=4*(n6)
*3n6=n*10+6;6n=6*Math.pow(10,i)+n;i代表的是6处在的是十位还是百位等等(十位i=1....)
*@paramargs
*/
publicstaticvoidmain(String[]args)
{
intn=0;//代表6的前面部分,“n6”
intN;//6移动前,即N=n6
intM;//6移动到数字首部后,即M=6n
intbuf;
inti=0;//代表数字的长度
while(true)//穷举
{
//移动前
N=n*10+6;
buf=n;
//计算数字的长度,确定6移到首部的权重,即:
6代表的是十位还是百位等等
while(buf!
=0)
{
i++;
buf=buf/10;
}
//移动后
M=(int)(6*Math.pow(10,i))+n;
//条件满足,输出,退出循环
if(M==(4*N))
{
System.out.print("要找的数为:
"+N);
break;
}
n++;//穷举变量修改
i=0;//长度值复位
}
}
}
1_4国际象棋有八行八列,64个单元格,在棋盘上摆放八个皇后,使其不能相互攻击,就是说任意两个皇后不能处在同一行,同一列或同一斜线上,问一共有多少中摆法
importjava.util.Arrays;
publicclassCh11_6
{
staticintresult=0;
staticint[]WeiZhi=newint[8];//全局数组,下标代表行,里面的元素代表列(就是我们上算法分析的解向量)
staticvoidEightQueen(intn)//算法
{
inti,j;
intct;//用于判断是否冲突,1代表不冲突
if(n==8)//若8个皇后已放置完成
{
System.out.println(Arrays.toString(WeiZhi));
result++;
return;
}
for(i=1;i<=8;i++)//试探
{
WeiZhi[n]=i;//在该列的第i行上放置
//断第n个皇后是否与前面皇后形成攻击
ct=1;
for(j=0;j{
if(WeiZhi[j]==WeiZhi[n])//形成攻击
{
ct=0;
}
elseif(Math.abs(WeiZhi[j]-WeiZhi[n])==(n-j))//形成攻击
{
ct=0;
}
else
{
}
}
if(ct==1)//没有冲突,就开始下一列的试探
EightQueen(n+1);//递归调用
}
}
publicstaticvoidmain(String[]args)
{
EightQueen(0);//求解
System.out.println("一共有"+result+"种解法");
}
}
1_5评委计分问题
问题描述:
有10个评委为参赛选手打分,分数是1到100。
选手最后的得分是:
去掉一个最高分,去掉一个最低分,其余8个评委取平均值。
importjava.util.Scanner;
publicclassCh11_7
{
publicstaticvoidmain(String[]args)
{
Scannerin=newScanner(System.in);
intnum,i,max,min,sum,avg;
max=0;/*先假设当前的最大值max为0*/
min=100;/*先假设当前的最小值min为100*/
sum=0;/*将求累加和变量的初值置为0*/
for(i=1;i<=10;i++)
{
System.out.print("请第"+i+"评委输入分数:
");
num=in.nextInt();/*输入评委的评分*/
sum+=num;/*计算总分*/
if(num>max)max=num;/*通过比较筛选出其中的最高分*/
if(num}
System.out.printf("去掉一个最高分:
%d\n去掉一个最低分:
%d",max,min);
avg=(sum-max-min)/8;
System.out.printf("\n平均得分:
%d",avg);/*输出结果*/
}
}
1_6罗马数字
将阿拉伯数字(0到1000)转换为罗马数字,对应关系如下表
1
2
3
4
5
6
7
8
9
Ⅰ
Ⅱ
Ⅲ
Ⅳ
Ⅴ
Ⅵ
Ⅶ
Ⅷ
Ⅸ
10
20
30
40
50
60
70
80
90
X
XX
XXX
XL
L
LX
LXX
LXXX
XC
100
200
300
400
500
600
700
800
900
C
CC
CCC
CD
D
DC
DCC
DCCC
CM
importjava.util.Scanner;
publicclassCh11_8
{
//建立对照表
staticStringa[][]={{"","I","II","III","IV","V","VI","VII","VIII","IX"},
{"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
{"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"}};
publicstaticvoidmain(Stringargs[])
{
Scannerin=newScanner(System.in);
System.out.print("请输入一个阿拉伯数字:
");
intn=in.nextInt();
intt=0;
System.out.printf("%d=",n);
inti=1000;
intfz;//分子
intfm;//分母
introw;
intcol;
for(intm=0;m<3;m++)
{
fz=n%i;//只取1000以下的数
fm=i/10;
t=fz/fm;//从高位向低位依次取出各位数字
row=2-m;
col=t;
System.out.printf("%s",a[row][col]+"\t");//对照表翻译输出
i=i/10;
}
System.out.printf("\n");
}
}
1_7找假币问题
问题描述:
现在有n枚硬币,其中一枚是假币,外观无法辩出。
只知道假币比真币稍轻。
要求仅仅使用一个天平,如何用最少的步骤找到假币?
该问题和二分法类似,可以用分治法解决。
importjava.util.Scanner;
publicclassCh11_9
{
staticfinalintMAXNUM=30;
staticintFalseCoin(intcoin[],intlow,inthigh)//算法
{
inti,sum1,sum2;
intre=0;
sum1=sum2=0;
if(low+1==high)//仅剩下两个硬币
{
if(coin[low]{
re=low+1;//下标从0开始,加1
returnre;
}
else
{
re=high+1;
returnre;
}
}
if((high-low+1)%2==0)//n是偶数
{
for(i=low;i<=low+(high-low)/2;i++)
{
sum1=sum1+coin[i];//前半段和
}
for(i=low+(high-low)/2+1;i<=high;i++)
{
sum2=sum2+coin[i];//后半段和
}
if(sum1>sum2)//前半段重,假币在后半段
{
re=FalseCoin(coin,low+(high-low)/2+1,high);//递归,在后半段中查询
returnre;
}
elseif(sum1{
re=FalseCoin(coin,low,low+(high-low)/2);//递归,在前半段中查询
returnre;
}
else
{
}
}
else//n是奇数
{
for(i=low;i<=low+(high-low)/2-1;i++)
{
sum1=sum1+coin[i];//前半段和
}
for(i=low+(high-low)/2+1;i<=high;i++)
{
sum2=sum2+coin[i];//后半段和
}
if(sum1>sum2)//前半段重,假币在后半段
{
re=FalseCoin(coin,low+(high-low)/2+1,high);//递归,在后半段中查询
returnre;
}
elseif(sum1{
re=FalseCoin(coin,low,low+(high-low)/2-1);//递归,在前半段中查询
returnre;
}
else//前后一样重,假币在中间
{
re=low+(high-low)/2+1;//计算中间位置
returnre;
}
}
returnre;
}
publicstaticvoidmain(String[]args)
{
int[]coin=newint[MAXNUM];
inti,n;
intweizhi;
System.out.println("分治算法求解假银币问题!
");
System.out.print("请输入银币总的个数:
");
Scannerinput=newScanner(System.in);
n=input.nextInt();//银币总的个数
System.out.print("请输入银币的真假:
1代表假币,2代表真币");
for(i=0;i{
coin[i]=input.nextInt();//输入银币的真假,1代表假币,2代表真币
}
weizhi=FalseCoin(coin,0,n-1);//调用求假币方法,求解
System.out.println("在上述"+n+"个银币中,第"+weizhi+"个银币是假的!
");
}
}
1_8窃贼问题(0-1背包问题)
问题描述:
有一个窃贼带着一个背包去偷东西,房间里有5件物品,其重量和价值如下:
物品一:
6公斤48元
物品二:
5公斤40元
物品三:
2公斤12元
物品四:
1公斤8元
物品五:
1公斤7元
窃贼希望拿到更大价值的东西,但是他的背包容量是8公斤,那么窃贼应该装上哪些东西才能达到要求?
分析:
这是一类典型的0-1背包问题下面我将提供两种解法:
回溯法和动态规划法
动态规划法解决0-1背包问题
动态规划法的核心就是递归方程。
如果你不能推出递归方程,那你就老老实实用回溯法吧
m(i,j)是背包容量为j,可选物品为0,1,...,i时0-1背包问题的最优值。
m(i,j)=0j=0
m(i,j)=0i=0&&jm(i,j)=vii=0&&j>=wi
m(i,j)=m(i-1,j)jm(i,j)=max{m(i-1,j),m(i-1,j-wi)+vi}j>=wi
publicclassCh11_10
{
//背包容量
privateintc;
//物品重量数组
privateint[]w;
//物品价值数组
privateint[]v;
privateint[][]m;//m(i,j)是背包容量为j,可选物品为0,1,...,i时0-1背包问题的最优值。
//记录结果
privateint[]x;
//最大价值
privateintmaxV;
//构造方法,数据初始化
publicCh11_10(int[]w,int[]v,intc)
{
this.w=w;
this.v=v;
this.c=c;
m=newint[w.length][c+1];
x=newint[w.length];
}
/**0-1背包问题动态规划求解
*递归式
*m(i,j)=0j=0
*m(i,j)