北大ACM试题1006

从这道题开始有点难度了。。。演化成数学模型的题目大意就是,有一个数,被23除p,被28除余e,被33除余i,然后减去d,最后是多少天。。。其实就是中国的剩余定理(传说中的韩信点兵。。),代码如下:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


public class Main_1006_Hanxin {


public static void main(String[] args) throws IOException {
Scanner cin = new Scanner(System.in);
List<String> input = new ArrayList<String>();
String temp = "";
while(!(temp = cin.nextLine()).contains("-1")){
input.add(temp);
}
cin.close();
for(int q=0;q<input.size();q++){
String[] s = input.get(q).split(" ");
int p = Integer.parseInt(s[0]);
int e = Integer.parseInt(s[1]);
int i = Integer.parseInt(s[2]);
int d = Integer.parseInt(s[3]);
//中国剩余定理
//使28*33的倍数被23除余1,先28*33mod23余4,即4的倍数除以23余1,其他类似
int sum = 23*28*33;
int output = (28*33*6*p + 23*33*19*e + 23*28*2*i - d +sum)%sum;
if(output == 0){
output = sum;
}
System.out.println("Case "+(q+1)+
": the next triple peak occurs in "+output+" days.");
}
}
}

当然也有笨方法,就是枚举咯。。。枚举也有枚举的方式,写的适用性稍微大了点

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


public class Main_1006_backup {


public static void main(String[] args) throws IOException {
Scanner cin = new Scanner(System.in);
List<Integer> circle = new ArrayList<Integer>();
circle.add(23);
circle.add(28);
circle.add(33);
List<Integer> output = new ArrayList<Integer>();
String temp = "";
while(!(temp = cin.nextLine()).contains("-1")){
String[] s = temp.split(" ");
int p = Integer.parseInt(s[0]);
int e = Integer.parseInt(s[1]);
int i = Integer.parseInt(s[2]);
int d = Integer.parseInt(s[3]);

                        //从1遍历到3个数的最小公倍数。。要想时间加快,直接用23*28*33代替就可以。。
for(int j=1;j<=minAllDivide(circle);j++){
if((j-p)%23 == 0 && (j-e)%28 == 0 && (j-i)%33 == 0){
if(j > d){
output.add(j - d);
}else{
output.add(23*28*33+j-d);
}

}
}
}
for(int i=0;i<output.size();i++){
System.out.println("Case "+(i+1)+
": the next triple peak occurs in "+output.get(i)+" days.");
}
cin.close();
}
//多个数的最小公倍数
public static int minAllDivide(List<Integer> n){
if(n.size() == 1){
return n.get(0);
}else if(n.size() == 2){
return minAllDivide(n.get(0),n.get(1));
}else{
List<Integer> copy = new ArrayList<Integer>();
for(int i=0;i<n.size()-1;i++){
copy.add(n.get(i));
}
return minAllDivide(minAllDivide(copy),n.get(n.size()-1));
}
}
//两个数的最小公倍数
public static int minAllDivide(int a,int b){
return a*b/maxAllDivided(a,b);
}
//两个数的最大公约数
public static int maxAllDivided(int a,int b){
if(a < b){
int temp = b;
b = a;
a = temp;
}
while(b != 0){
int temp = a % b;
a = b;
b = temp;
}
return a;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值