目录
第1题 好好学习
一、标题:好好学习
汤姆跟爷爷来中国旅游。一天,他帮助中国的小朋友贴标语。他负责贴的标语是分别写在四块红纸上的四个大字:“好、好、学、习”。但是汤姆不认识汉字,他就想胡乱地贴成一行。
请你替小汤姆算一下,他这样乱贴,恰好贴对的概率是多少?
答案是一个分数,请表示为两个整数比值的形式。例如:1/3 或 2/15 等。
如果能够约分,请输出约分后的结果。
注意:不要书写多余的空格。
请严格按照格式,通过浏览器提交答案。
注意:只提交这个比值,不要写其它附加内容,比如:说明性的文字。
1 / 12
思路:(暴力破解)算出总的结果,再算出排对的总数,计算出的结果是2/24,约分后的结果是1/12
public class Main {
public static void main(String[] args) {
int count = 0;
int count1 = 0;
for(int i=1;i<=4;i++){//好好学习
for(int j=1;j<=4;j++){
for(int m=1;m<=4;m++){
for(int n=1;n<=4;n++){
if(i==j||i==m||i==n||j==m||j==n||m==n){//四张不能重复
continue;
}
if(i==1&&j==2&&m==3&&n==4){
count1++;
}
if(j==1&&i==2&&m==3&&n==4){
count1++;
}
count++;//总数
System.out.println(i+" "+j+" "+m+" "+n);
}
}
}
}
System.out.println(count1+"/"+count);
}
}
//1/12
第2题 埃及分数
二、标题:埃及分数
古埃及曾经创造出灿烂的人类文明,他们的分数表示却很令人不解。古埃及喜欢把一个分数分解为类似: 1/a + 1/b 的格式。
这里,a 和 b 必须是不同的两个整数,分子必须为 1
比如,2/15 一共有 4 种不同的分解法(姑且称为埃及分解法):
1/8 + 1/120
1/9 + 1/45
1/10 + 1/30
1/12 + 1/20
那么, 2/45 一共有多少个不同的埃及分解呢(满足加法交换律的算同种分解)? 请直接提交该整数(千万不要提交详细的分解式!)。
请严格按照要求,通过浏览器提交答案。
注意:只提交分解的种类数,不要写其它附加内容,比如:说明性的文字
7
思路:(暴力破解)根据分母统分计算出所有符合的,然后计算总数,由于(满足加法交换律的算同种分解)所以再除以2好了。
public class Main {
public static void main(String[] args) {
int m = 45;
int count = 0;
for(int a=2;a<m*m;a++){
for(int b=2;b<m*m;b++){
if(a==b){
continue;
}
if((a+b)*m==2*a*b){
count++;
System.out.println("1/"+a+"+1/"+b);
}
}
}
System.out.println(count);
}
}
//7
第3题 金蝉素数
标题:金蝉素数
考古发现某古墓石碑上刻着一个数字:13597,后研究发现:
这是一个素数!
并且,去掉首尾数字仍是素数!
并且,最中间的数字也是素数!
这样特征的数字还有哪些呢?通过以下程序的帮助可以轻松解决。请仔细阅读代码,并填写划线部分缺失的代码。
public class A
{
static boolean isPrime(int n)
{
if(n<=1) return false;
for(int i=2; i*i<=n; i++){
if(n%i==0) return false;
}
return true;
}
static void f(int[] x, int k)
{
if(_____________________________){ // 填空位置
if(isPrime(x[0]*10000 + x[1]*1000 + x[2]*100 + x[3]*10 + x[4]) &&
isPrime(x[1]*100 + x[2]*10 + x[3]) &&
isPrime(x[2]))
System.out.println(""+x[0]+x[1]+x[2]+x[3]+x[4]);
return;
}
for(int i=k; i<x.length; i++){
{int tmp=x[k]; x[k]=x[i]; x[i]=tmp; }
f(x,k+1);
{int tmp=x[k]; x[k]=x[i]; x[i]=tmp; }
}
}
static void test()
{
int[] x = {1,3,5,7,9};
f(x,0);
}
public static void main(String[] args)
{
test();
}
}
请分析代码逻辑,并推测划线处的代码,通过网页提交。
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!
k == x.length
思路:观察代码可以发现,要填的位置其实是递归的一个出口,当传入的那个数大于等于数组的长度的时候,不符合,然后调出递归。
public class Main {
static boolean isPrime(int n)
{
if(n<=1) return false;
for(int i=2; i*i<=n; i++){
if(n%i==0) return false;
}
return true;
}
static void f(int[] x, int k)
{
if(k>=x.length){ // 填空位置
if(isPrime(x[0]*10000 + x[1]*1000 + x[2]*100 + x[3]*10 + x[4]) &&
isPrime(x[1]*100 + x[2]*10 + x[3]) &&
isPrime(x[2]))
System.out.println(""+x[0]+x[1]+x[2]+x[3]+x[4]);
return;
}
for(int i=k; i<x.length; i++){
{int tmp=x[k]; x[k]=x[i]; x[i]=tmp; }
f(x,k+1);
{int tmp=x[k]; x[k]=x[i]; x[i]=tmp; }
}
}
static void test()
{
int[] x = {1,3,5,7,9};
f(x,0);
}
public static void main(String[] args)
{
test();
}
}
//k>=x.length
第4题 横向打印二叉树
四、标题:横向打印二叉树
二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如图1所示。
本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。
输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。
输入数据中没有重复的数字。
输出该排序二叉树的横向表示。 对应上例中的数据,应输出:
|-12
10-|
|-8-|
| |-7
|-5-|
|-4为了便于评卷程序比对空格的数目,请把空格用句点代替:
...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4
例如:
用户输入:
10 5 20
则程序输出:
...|-20
10-|
...|-5再例如:
用户输入:
5 10 20 8 4 7
则程序输出:
.......|-20
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
思路:因为这是一个二叉树,所以需要用到节点,观察输出时的规律,由于每一个数占一行,可以在节点这里声明
一个String类型保存输出时的字符,添加到数的左右节点时,需要考虑加入多少个.或| 。这里需要注意字符的处理。
public class Main {
static class Node{
int data;
Node left;
Node right;
String s;
public Node(int e){
this.data = e;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] nn = in.nextLine().split(" ");
int [] n = new int [nn.length];
for(int i=0;i<nn.length;i++){
n[i] = Integer.parseInt(nn[i]);
}
Node root = new Node(n[0]);
root.s = root.data+"-|";
for(int i=1;i<n.length;i++){
Node node = new Node(n[i]);
if(node.data>root.data){
addRight(node,root,0);
}else{
addLeft(node,root,0);
}
}
print(root);
}
private static void print(Node root) {
// TODO Auto-generated method stub
if(root.right!=null)
print(root.right);
if(root.right==null&&root.left==null){
System.out.println(root.s.substring(0,root.s.length()-2));
}else
System.out.println(root.s);
if(root.left!=null)
print(root.left);
}
private static void addRight(Node node, Node root, int flag) {
// TODO Auto-generated method stub
if(root.right==null){
node.s = root.s.replaceAll("[0-9]|-", ".").substring(0,root.s.length()-1);
if(flag == 0){
int index = node.s.lastIndexOf("|");
if(index!=-1){
node.s = node.s.substring(0,index)+"."+node.s.substring(index+1);
}
}
node.s += "|-"+node.data+"-|";
root.right = node;
}else if(node.data>root.right.data){
addRight(node, root.right, 0);
}else{
addLeft(node, root.right, 1);
}
}
private static void addLeft(Node node, Node root, int flag) {
// TODO Auto-generated method stub
if(root.left==null){
node.s = root.s.replaceAll("[0-9]|-", ".").substring(0,root.s.length()-1);
if(flag == 0){
int index = node.s.lastIndexOf("|");
if(index!=-1){
node.s = node.s.substring(0,index)+"."+node.s.substring(index+1);
}
}
node.s += "|-"+node.data+"-|";
root.left = node;
}else if(node.data>root.left.data){
addRight(node, root.left, 1);
}else{
addLeft(node, root.left, 0);
}
}
}
第5题 危险系数
五、标题:危险系数
抗日战争时期,冀中平原的地道战曾发挥重要作用。
地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。
我们来定义一个危险系数DF(x,y):
对于两个站点x和y (x != y), 如果能找到一个站点z,当z被敌人破坏后,x和y不连通,那么我们称z为关于x,y的关键点。相应的,对于任意一对站点x和y,危险系数DF(x,y)就表示为这两点之间的关键点个数。
本题的任务是:已知网络结构,求两站点之间的危险系数。
输入数据第一行包含2个整数n(2 <= n <= 1000), m(0 <= m <= 2000),分别代表站点数,通道数;
接下来m行,每行两个整数 u,v (1 <= u, v <= n; u != v)代表一条通道;
最后1行,两个数u,v,代表询问两点之间的危险系数DF(u, v)。
输出:一个整数,如果询问的两点不连通则输出-1.
例如:
用户输入:
7 6
1 3
2 3
3 4
3 5
4 5
5 6
1 6
则程序应该输出:
2资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
思路:需要把困难的转化为简单的问题,记录有多少条路,以及每个点所经过的次数,如果路数与点的经过的次数相同,
则这个点为关键点,然后算出这样点的个数就好了。
import java.util.Scanner;
public class Main {
public static int [][] map;//图
public static int n,m,start,end;
public static int [] visit;//有没有访问
public static int [] way;//经过的点
public static int ans;//路径数
public static int [] cnt;//点的次数
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
map = new int [n+1][n+1];
visit = new int [n+1];
way = new int [n+1];
cnt = new int [n+1];
for(int i=1;i<=m;i++){
int a = in.nextInt();
int b = in.nextInt();
map[a][b] = 1;
map[b][a] = 1;
}
start = in.nextInt();
end = in.nextInt();
dfs(start,end,0);
int count = 0;
for(int i=1;i<=n;i++){
if(cnt[i]==ans){
count++;
}
}
System.out.println(count-2);
}
public static void dfs(int start,int end,int temp){
visit[start] = 1;
way[temp] = start;
if(start==end){
ans++;
for(int j=0;j<=temp;j++){
cnt[way[j]]++;
}
}
for(int i=1;i<=n;i++){
if(map[start][i]==1&&visit[i]!=1){
visit[i] = 1;
dfs(i,end,temp+1);
visit[i] = 0;
}
}
}
}
第6题 公式求值
6、标题:公式求值
输入n, m, k,输出图1所示的公式的值。其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数。组合数的计算公式如图2所示。
输入的第一行包含一个整数n;第二行包含一个整数m,第三行包含一个整数k。
计算图1所示的公式的值,由于答案非常大,请输出这个值除以999101的余数。
【样例输入1】
3
1
3
【样例输出1】
162【样例输入2】
20
10
10
【样例输出2】
359316
【数据规模与约定】
对于10%的数据,n≤10,k≤3;
对于20%的数据,n≤20,k≤3;
对于30%的数据,n≤1000,k≤5;
对于40%的数据,n≤10^7,k≤10;
对于60%的数据,n≤10^15,k ≤100;
对于70%的数据,n≤10^100,k≤200;
对于80%的数据,n≤10^500,k ≤500;
对于100%的数据,n在十进制下不超过1000位,即1≤n<10^1000,1≤k≤1000,同时0≤m≤n,k≤n。
【提示】
999101是一个质数;
当n位数比较多时,绝大多数情况下答案都是0,但评测的时候会选取一些答案不是0的数据;资源约定:
峰值内存消耗(含虚拟机) < 128M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
没写出来>-<
下面代码来自:作者:林梵 来源:CSDN 原文:https://blog.csdn.net/u010836847/article/details/21166725?utm_source=copy
import java.math.BigInteger;
import java.util.Scanner;
// 正确
public class test2 {
public static BigInteger lucas(BigInteger n,BigInteger m,BigInteger p){
if(m.equals(BigInteger.ZERO)) return BigInteger.ONE;
return BigInteger.valueOf(f(n.mod(p).longValue(),m.mod(p).longValue())).multiply(lucas(n.divide(p),m.divide(p),p)).mod(p);
}
public static long f(long n,long m){
if(m>n) return 1;
if(n==m|| m==0) return 1;
if(m>n-m) m=n-m;
long tmpi=1,tmpn=1,s1=1,s2=1,ans=1;
for (int i = 1; i<=m; i++) {
tmpi=i;
tmpn=n-i+1;
s1=s1*tmpi%999101;
s2=s2*tmpn%999101;
}
ans = s2*pow1(s1,999099)%999101;
return ans%999101;
}
public static long pow1(long x,long n) {
if(x==1) return 1;
if (n==0)
return 1;
else {
while ((n & 1)==0) {
n>>=1;
x=(x *x)%999101;
}
}
long result = x%999101;
n>>=1;
while (n!=0) {
x=(x *x)%999101;;
if ((n & 1)!=0)
result =result*x%999101;
n>>=1;
}
return result;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
BigInteger n = new BigInteger(sc.nextLine());
BigInteger m = new BigInteger(sc.nextLine());
int k = Integer.parseInt(sc.nextLine());
// long start = System.currentTimeMillis();
BigInteger md = new BigInteger("999101");
long Cnm=lucas(n, m,md).longValue()%999101;
long sum = 0;
if(Cnm!=0){
int[][] a = new int[k][k];
int h = 1;
for (int i = 0; i < k; i++) {
for (int j = 0; j < k; j++) {
if (j >= h)
a[i][j] =0;
else {
if (j == 0 || j == h - 1)
a[i][j] = 1;
else {
a[i][j] = (a[i - 1][j - 1]*(h - j)+a[i - 1][j])%999101;
}
}
}
h++;
}
long m1 = 1,n1 =1;
long x=n.subtract(new BigInteger(k+"")).mod(md.subtract(BigInteger.ONE)).longValue();
long n3 = pow1(2,x);
// System.out.println("n3:"+n3);
for (int i = k - 1; i >= 0; i--) {
n1=n3*pow1(2,i)%999101;
// System.out.println("n1:"+n1);
m1 = m1*(n.subtract(new BigInteger((k - 1 - i) + "")).mod(md).longValue())%999101;
// System.out.println(m1+" "+a[k - 1][i]);
sum = (sum+m1*a[k - 1][i]*n1)%999101;
// System.out.println("sum:"+sum);
}
sum = sum*Cnm%999101;
}
System.out.println(sum);
// long end = System.currentTimeMillis();
// System.out.println(end - start);
}
}