目录
1.购物单
小明刚刚找到工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦,但又不好推辞。
这不,大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠的。
小明也有个怪癖,不到万不得已,从不刷卡,直接现金搞定。
现在小明很心烦,请你帮他计算一下,需要从取款机上取多少现金,才能搞定这次购物。
取款机只能提供 100100100 元面额的纸币。小明想尽可能少取些现金,够用就行了。 你的任务是计算出,小明最少需要取多少现金。
以下是让人头疼的购物单,为了保护隐私,物品名称被隐藏了。
本题使用excel,直接求得,不太了解excel的,一定百度看看。
答案5200
2.纸牌三角形
题目:
A,2,3,4,5,6,7,8,9 共 999 张纸牌排成一个正三角形(AAA 按 111 计算)。要求每个边的和相等。 下图就是一种排法。
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
这道题最直观的方法,就是把所有能够有的可能都一一尝试,然后判断,毕竟只是一个“填空题”还是“第二题”。。。
首先需要解决全排列问题
public void swap(int [] arr,int i,int j){
// 交换函数
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 对数组arr进行全排列
public void perum(int [] arr,int left,int right ){
// for循环将数组中所有的元素和第一个元素进行交换。然后进行全排列。
// 递归结束条件
if(left == right){
// 一次递归结束。将整个数组打印出来
pringArray( arr,left+1);
}
for(int i =left ;i <= right;i++){
swap(arr,i,left);
// 把剩下的元素都做全排列。
perum(arr,left+1,right);
// 然后再交换回去,数组还原,保证下一次不会有重复交换。
swap(arr,i,left);
}
}
public void pringArray(int [] arr,int n){
// 打印数组
for (int i = 0; i < n; i++) {
System.out.print(arr[i]);
}
System.out.println();
}
@Test
public void test1() {
int arr[] ={1,2,3};
Main practice_perum = new Main();
practice_perum.perum(arr,0,arr.length-1);
}
全排列的测试结果是这样
然后再根据全排列的结果去判断是否符合题意
int arr[] ={1,2,3,4,5,6,7,8,9};
Main practice_perum = new Main();
practice_perum.perum(arr,0,arr.length-1);
System.out.println(count/3/2);//以为有旋转还有镜像的原因,所以除于六的出的是正确答案
得到正确答案144
3.承压计算
这道题也是直接做,就是要处理边界问题,所以提前把边界填上0的话,会好处理特别特别多。
public static void main(String[] args) {
int[] a= {7,
5,8,
7,8,8,
9,2,7,2,
8,1,4,9,1,
8,1,8,8,4,1,
7,9,6,1,4,5,4,
5,6,5,5,6,9,5,6,
5,5,4,7,9,3,5,5,1,
7,5,7,9,7,4,7,3,3,1,
4,6,4,5,5,8,8,3,2,4,3,
1,1,3,3,1,6,6,5,5,4,4,2,
9,9,9,2,1,9,1,9,2,9,5,7,9,
4,3,3,7,7,9,3,6,1,3,8,8,3,7,
3,6,8,1,5,3,9,5,8,3,8,1,8,3,3,
8,3,2,3,3,5,5,8,5,4,2,8,6,7,6,9,
8,1,8,1,8,4,6,2,2,1,7,9,4,2,3,3,4,
2,8,4,2,2,9,9,2,8,3,4,9,6,3,9,4,6,9,
7,9,7,4,9,7,6,6,2,8,9,4,1,8,1,7,2,1,6,
9,2,8,6,4,2,7,9,5,4,1,2,5,1,7,3,9,8,3,3,
5,2,1,6,7,9,3,2,8,9,5,5,6,6,6,2,1,8,7,9,9,
6,7,1,8,8,7,5,3,6,5,4,7,3,4,6,7,8,1,3,2,7,4,
2,2,6,3,5,3,4,9,2,4,5,7,6,6,3,2,7,2,4,8,5,5,4,
7,4,4,5,8,3,3,8,1,8,6,3,2,1,6,2,6,4,6,3,8,2,9,6,
1,2,4,1,3,3,5,3,4,9,6,3,8,6,5,9,1,5,3,2,6,8,8,5,3,
2,2,7,9,3,3,2,8,6,9,8,4,4,9,5,8,2,6,3,4,8,4,9,3,8,8,
7,7,7,9,7,5,2,7,9,2,5,1,9,2,6,5,3,9,3,5,7,3,5,4,2,8,9,
7,7,6,6,8,7,5,5,8,2,4,7,7,4,7,2,6,9,2,1,8,2,9,8,5,7,3,6,
5,9,4,5,5,7,5,5,6,3,5,3,9,5,8,9,5,4,1,2,6,1,4,3,5,3,2,4,1};
double[][] nums=new double[30][];
int n=0;
//将数据处理到二维数组中
for(int i=0;i<29;i++) {
System.out.print("这是"+i+" ");
double[] temp=new double[i+1];
for(int j=0;j<=i;j++) {
temp[j]=a[n];
n++;
System.out.print(temp[j]+" ");
}
nums[i]=temp;
System.out.println();
}
//需要求的那一行在第30行 有30个数 即是nums[29]
nums[29]=new double[30];
//先计算前面重量的累计
for(int i=1;i<29;i++){
for(int j=0;j<=i;j++){//每一个块此时的重量应该是自己加上上面压下来的部分
if(j==0) {//因为一开始没有设置边界 所以这个时候要考虑边界问题
nums[i][j]+=nums[i-1][j]/2.0;
}else if(j==i) {
nums[i][j]+=nums[i-1][j-1]/2.0;
}else {
nums[i][j]+=nums[i-1][j-1]/2.0+nums[i-1][j]/2.0;
}
}
}
double max=0,min=1e6+5;
for(int i=0;i<30;i++){//计算第30层每个电子秤的承重
if(i==0) {
nums[29][i]=nums[28][i]/2;
}else if(i==29) {
nums[29][i]=nums[28][i-1]/2;
}else {
nums[29][i]=nums[28][i-1]/2+nums[28][i]/2;
}
System.out.println(nums[29][i]);
if(nums[29][i]>max)
max=nums[29][i];
if(nums[29][i]<min)
min=nums[29][i];
}
//因为我们不知道电子秤的计数规则,所以我们必须要换算一下,因为我们测的本来就和题目中的最小不一样
//min*x=2086458231
//max*x=所求值
System.out.println((2086458231/min)*max);
}
4.魔方状态
5.取位数
求1个整数的第k位数字有很多种方法。 以下的方法就是一种。
请仔细分析源码,填写划线部分缺少的内容。
没啥难度
public class Main {
static int len(int x){//得到的是位数
if(x<10) return 1;
return len(x/10)+1;
}
// 取x的第k位数字
static int f(int x, int k){
if(len(x)-k==0) return x%10;//等于说一直缩小到位数到想要的 然后再对个位取余
return ______; //填空 f(x/10,k)
}
public static void main(String[] args)
{
int x = 23513;
//System.out.println(len(x));
System.out.println(f(x,3));
System.out.println(135%10);
System.out.println(f(893275,2));
}
}
6.最大公共子串
static int f(String s1, String s2)
{
char[] c1 = s1.toCharArray();
char[] c2 = s2.toCharArray();
int[][] a = new int[c1.length+1][c2.length+1];
int max = 0;
for(int i=1; i<a.length; i++){
for(int j=1; j<a[i].length; j++){
if(c1[i-1]==c2[j-1]) {
a[i][j] =_______;//代码补齐 a[i-1][j-1]+1
if(a[i][j] > max) max = a[i][j];
}
}
}
return max;
}
public static void main(String[] args){
int n = f("abcdkkk", "baabcdadabc");
System.out.println(n);
System.out.println(f("aaakkkabababa", "baabababcdadabc"));
System.out.println(f("abccbaacbcca", "ccccbbbbbaaaa"));
System.out.println(f("abcd", "xyz"));
System.out.println(f("ab", "ab"));
}
7.日期问题
这个虽然不是一道难题,但是好花时间,而且有很多可以调整优化的地方。就是暴力的方式来做,没有什么算法。但是我实在不想做了,可以从判断日期是否合法的角度调优
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
String str=scan.nextLine();//输入
int[] data=new int[6];//创建一个存储数字的数组
for(int i=0,j=0;i<str.length();i++) {//将字符串中的数字放到数组
if(str.charAt(i)=='/') {
//什么也不干
}else {
data[j]=str.charAt(i)-48;
j++;
}
}
int t1=data[0]*10+data[1];
int t2=data[2]*10+data[3];
int t3=data[4]*10+data[5];
Riqi time1=new Riqi(1900+t1,t2,t3);
Riqi time2=new Riqi(2000+t1,t2,t3);
Riqi time3=new Riqi(1900+t3,t1,t2);
Riqi time4=new Riqi(2000+t3,t1,t2);
Riqi time5=new Riqi(1900+t3,t2,t1);
Riqi time6=new Riqi(2000+t3,t2,t1);
Riqi[] times= {time1,time2,time3,time4,time5,time6};
//去重
List<String> list=new ArrayList<>();
for(Riqi timeN:times) {
if(panduan(timeN)) {
if(!list.contains(timeN.toString())) {
timeN.PrintF();
System.out.println();
}
list.add(timeN.toString());
}
}
scan.close();
}
//判断日期是否合法的方法
public static boolean panduan(Riqi time) {
int[] mouthOrder= {0,31,28,31,30,31,30,31,31,30,31,30,31};
if(time.year>2059||time.year<1960||time.mouth>12||time.day>31) {//初步筛选
return false;
}
if(time.year%4==0&&time.year%100!=0) {//闰年的话 需要遵守这个规则
if(time.mouth==2) {//闰年的二月
if(time.day>29) {
return false;
}
}else if(time.day>mouthOrder[time.mouth]) {//闰年的其他月份
return false;
}
}else if(time.day>mouthOrder[time.mouth]) { //不闰年的话 这个规则
return false;
}
return true;
}
}
class Riqi{
int year;
int mouth;
int day;
public Riqi() {
super();
}
public Riqi(int year, int mouth, int day) {
super();
this.year = year;
this.mouth = mouth;
this.day = day;
}
//可以调整输出的格式 xxxx/xx/xx
public void PrintF() {
System.out.printf("%d-%02d-%02d",year,mouth,day);
}
//没有使用这个
@Override
public String toString() {
return year + "-" + mouth + "-" + day;
}
}
8.包子凑数
题目的意思就是题目的意思,。。。。,
总的来说,我们可以分成两个情况,笼屉大小的最大公约数,是否为1.比如说,如果有两个笼屉,分别为2,4,那么他们的最大公约数为2,而且他们是拼不出任何一个奇数的,其他公约数不为1的情况都同理,都有无限个凑不出的情况。只有公约数为1的才有有限个。
在求是否可以凑出的时候,我们可以看,剪去一个笼屉是否能够凑出,如果前一个可以,那么这个也可以,具体的过程如果自己画一遍的话,就容易理解了
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
int n=scan.nextInt();//N
int arr[] = new int[102];//每个笼屉能够装的数量
arr[1]=scan.nextInt();
int temp=arr[1];
//获得arr 并且得到最大公约数
for(int i=2;i<=n;i++) {
arr[i]=scan.nextInt();
temp=gcd(temp, arr[i]);
}
//结果数组
int[] dp = new int[100004];
dp[0]=1;
for(int i=1;i<=n;i++) {
for(int j=arr[i];j<100004;j++) {//画一画就容易理解
if(dp[j-arr[i]]==1)
dp[j]=1;
}
}
int ans=0;
for(int i=1;i<100004;i++) {
if(dp[i]!=1)
ans++;
}
if(temp>1) {
System.out.println("INF");
}else {
System.out.println(ans);
}
scan.close();
}
//求最大公约数
private static int gcd(int a, int b) {
// TODO Auto-generated method stub
return b==0?a:gcd(b,a%b);
}