目录
(4) 填空题 跑步锻炼 10分
题目描述
小蓝每天都锻炼身体。
正常情况下,小蓝每天跑 11 千米。如果某天是周一或者月初(11 日),为了激励自己,小蓝要跑 22 千米。如果同时是周一或月初,小蓝也是跑 22 千米。
小蓝跑步已经坚持了很长时间,从 2000年 11 月 11 日周六(含)到 2020 年 10 月 11 日周四(含)。请问这段时间小蓝总共跑步多少千米?
【思路】暴力,注意闰年的判断后二月份赋值为29,最后10月份可用三目运算符进行选择
import java.util.*;
public class Main{
static boolean isryear(int year){
if(year%400==0||(year%4==0&&year%100!=0))
return true;
else return false;
}
public static void main(String[] args){
int a[]=new int[13];
a[1]=31;a[2]=28;a[3]=31;a[4]=30;a[5]=31;a[6]=30;a[7]=31;a[8]=31;
a[9]=30;a[10]=31;a[11]=30;a[12]=31;
int week=6;
int sum=0;
for(int i=2000;i<=2020;i++){
if(isryear(i))a[2]=29;
else a[2]=28;
for(int j=1;j<=(i==2020?10:12);j++){
if(i==2020&&j==10)a[10]=1;
for(int k=1;k<=a[j];k++){
if(k==1||week==1)
sum+=2;
else
sum+=1;
week=(week+1)%7;
}}}
System.out.println(sum);
}
}
(5) 填空题 七段码 15分
小蓝要用七段码数码管来表示一种特殊的文字。
上图给出了七段码数码管的一个图示,数码管中一共有 77 段可以发光的二极管,分别标记为 a, b, c, d, e, f, ga,b,c,d,e,f,g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
【思路】图形联通块使用DFS -->用7位二进制数表示7个二极管,邻接矩阵表示连接状态
-->先选择可用顶点再判断能否连通
import java.util.*;
public class Main{
static int[][] Edge=new int[7][7];
static int[] choose=new int[7];//选中顶点
static int[] visited=new int[7];//纪录顶点是否访问过
static void dfs(int k){
for(int i=0;i<7;i++){
//顶点可连接,选中但未访问将搜索下一可连接顶点
//dfs深度搜索,一条路走到底
if(Edge[k][i]==1&&choose[i]==1&&visited[i]==0)
{visited[i]=1;dfs(i);}
}
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
for(int i=0;i<7;i++)
for(int j=0;j<7;j++)
Edge[i][j]=scan.nextInt();
int i,j,k,x=0,ans=127;
for( i=1;i<=127;i++){
Arrays.fill(choose,0);
Arrays.fill(visited,0);
x=i;j=0;k=0;
//127种方案,先选择可用顶点再考虑是否能走通
//x=3,ab都被选中,x=127,abcdef全选中,先摩2再除二相当于十进制转2进制数
while(x!=0){
if(x%2==1)choose[j]=1;
x/=2;j++;}
//选中的第一个顶点标记访问并进行深度搜索
while(choose[k]==0)k++;
visited[k]=1;
dfs(k);
for(j=0;j<7;j++){
if(choose[j]==1&&visited[j]==0)break;}//选中但未访问
if(j<7) ans--;
else {
int tmp=0;
for(k=0;k<7;k++){
if(choose[k]==1){tmp='a'+k;System.out.print((char)tmp);}
}
System.out.println();
}
}
System.out.println(ans);
//47
/*邻接矩阵
a b c d e f g
0 1 0 0 0 1 0
1 0 1 0 0 0 1
0 1 0 1 0 0 1
0 0 1 0 1 0 0
0 0 0 1 0 1 1
1 0 0 0 1 0 1
0 1 1 0 1 1 0
*/
}
}
【答案】80
(6)程序设计题 成绩统计 15分
题目描述
小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。
如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。
请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整 数。
输入描述
输入的第一行包含一个整数 n\ (1 \leq n \leq 10^4)n (1≤n≤104),表示考试人数。
接下来 nn 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。
输出描述
输出两行,每行一个百分数,分别表示及格率和优秀率。百分号前的部分 四舍五入保留整数。
输入输出样例
示例:
输入
7
80
92
56
74
88
100
0
输出:
71%
43%
import java.util.*;
public class Main{
public static void main(String[] args){
int sum1=0,sum2=0;
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
for(int i=0;i<n;i++){
int m=scan.nextInt();
if(m>=60&&m<=100)
sum1+=1;
if(m>=85&&m<=100)
sum2+=1;
}
sum1=(int)(100.0*sum1/n+0.5);
sum2=(int)(100.0*sum2/n+0.5);
System.out.println(sum1+"%");
System.out.println(sum2+"%");
}
}
(7)程序设计题 回文日期 20分
题目描述
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。
有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算 “千年两遇”。
给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
输入描述
输入包含一个八位整数 NN,表示日期。
对于所有评测用例,10000101 \leq N \leq 8999123110000101≤N≤89991231,保证 NN 是一个合法日期的 8 位数表示。
输出描述
输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。
输入输出样例
示例
输入
20200202
输出
20211202
21211212
//20200202 20211202 21211212(ababbaba)
import java.util.*;
public class Main {
public static boolean isrunyear(int year){
if(year%400==0||(year%4==0&&year%100!=0))
return true;
else return false;}
public static void main(String[] args) {
int[] a=new int[13];
a[1]=31;a[2]=28;a[3]=31;a[4]=30;a[5]=31;a[6]=30;
a[7]=31;a[8]=31;a[9]=30;a[10]=31;a[11]=30;a[12]=31;
Scanner scan=new Scanner(System.in);
int get=scan.nextInt();
int get1=0,get2=0;
int md=get%10000;
int gj=0,m=0,n=0,month=0,day=0;
get1=get/10000;//2020
int k,i;
for( i=get1;i<9999;i++){
k=3;gj=i;m=0;n=0;
if(isrunyear(gj))a[2]=29;
else a[2]=28;
while(gj!=0){
m=gj%10;//0
n=n+m*(int)Math.pow(10.0,k*1.0);
gj/=10;//202
k--;
}
month=n/100;
day=n%100;
if(month<=12&&day<=a[month])
if(i==get1&&(i*10000+n)>get)
break;
else if(i>get1)break;
}
System.out.println(i*10000+n);
int flag=1;
n=0;m=0;
gj=0;
get2=get/1000000;
int j,ans=0;
while(flag==1&&get2<=99){
gj=get2;//21
m=gj%10;//1
gj/=10;//2
n=m*10+gj;
if(n<=12)ans=get2*1000000+get2*10000+n*100+n;
if(ans>get)flag=0;
get2++;
}
System.out.println(ans);
}
}
(8)程序设计题 子串分值和 20分
题目描述
对于一个字符串 SS,我们定义 SS 的分值 f(S)f(S) 为 SS 中出现的不同的字符个数。例如 f(“aba”) = 2,f(“abc”) = 3, f(“aaa”) = 1f(“aba”)=2,f(“abc”)=3,f(“aaa”)=1。
现在给定一个字符串 S [0...n − 1]S[0...n−1](长度为 nn),请你计算对于所有 SS 的非空子串 S [i...j](0 ≤ i ≤ j < n)S[i...j](0≤i≤j<n),f(S [i...j])f(S[i...j]) 的和是多少。
输入描述
输入一行包含一个由小写字母组成的字符串 SS。
其中,1 ≤ n ≤ 10^51≤n≤105。
输出描述
输出一个整数表示答案。
输入输出样例
示例 1
输入
ababc
输出
28
//枚举每个子串O(n2),再历遍子串中的每个字母O(n),复杂度为O(n3)将复杂度为三次方转化为一倍的时间复杂度,统计每个字母对答案的贡献
//数组word用于统计26个字母最后出现的位置,初始化为数组长度加一,通过公式i*(word[i]-1)得到当前字母对答案的贡献
/*示例:
i 1 2 3 4 5
get[] a b a b c
word[] 3 4 6 6 6
先统计c的贡献为(6-5)*5
*/
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scan=new Scanner(System.in);
String str=scan.nextLine();
String[] get=str.split("");
int[] word=new int[26];
int n=str.length();
Arrays.fill(word,n+1);
long ans=0;
for(int i=n;i>=1;i--){
int lastw=;
ans+=(long)i*(word[get[i-1].charAt(0)-'a']-i);
word[get[i-1].charAt(0)-'a']=i;
}
System.out.println(ans);
}}
(9)程序设计题 平面切分 25分
(10)程序设计题 字串排序 25分