19201419曾宇杰
题目:第十一届蓝桥杯大赛软件类省赛第二场C/C++大学B组试题
试题A:门牌制作
【问题描述】
小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字
符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、 0、 1、 7,即需要 1 个
字符 0, 2 个字符 1, 1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?
【答案提交】
624
public class Q_A {
public static void main(String[] args){
int ans = 0;
for(int i = 1; i <= 2020; i++){
int j = i;
while(j != 0){
if(j % 10 == 2){
ans++;
}
j /= 10;
}
}
System.out.println(ans);
}
}
试题 B: 既约分数
【问题描述】
如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。
请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1
和 2020)?
【答案提交】
2481215
public class Q_B {
public static void main(String[] args) {
int ans = 0;
for(int i = 1; i <= 2020; i++){
for(int j = 1; j <= 2020; j++){
if(gcd(i, j) == 1){
ans++;
}
}
}
System.out.println(ans);
}
public static int gcd(int a,int b) {
if (b == 0)
return a;
else
return gcd(b, a % b);
}
}
试题 C: 蛇形填数
【问题描述】
如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 :::
3 5 8 14 :::
4 9 13 :::
10 12 :::
11 :::
:::
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列
的数是多少 ?
【答案提交】
761
public class Q_C {
public static void main(String[] args) {
int[][] a = new int[50][50];
int n = 45, num = 45 * 45;
for(int i = 1, cnt = 1; i <= n && cnt <= num; i++){
if((i & 1) == 1){
for(int x = i, y = 1; x >= 1 && y <= i; x--, y++){
a[x][y] = cnt++;
}
} else {
for(int x = 1, y = i; x <= i && y >= 1; x++, y--){
a[x][y] = cnt++;
}
}
}
System.out.println(a[20][20]);
}
}
试题 D: 跑步锻炼
【问题描述】
小蓝每天都锻炼身体。
正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初(1 日),为了
激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。
小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年
10 月 1 日周四(含)。请问这段时间小蓝总共跑步多少千米?
【答案提交】
8879
public class Q_D {
public static void main(String[] args) {
int[] M = {0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int y = 2000, m = 1, d = 1, w = 6, ans = 2;
while(y != 2020 || m != 10 || d != 1) {
if(y % 400 == 0 || ((y % 4 == 0) && (y % 100 != 0))){
M[2] = 29;
} else {
M[2] = 28;
}
d++;
w = (w + 1) % 7;
if(d > M[m]){
d = 1;
m++;
if(m > 12){
m = 1;
y++;
}
}
if(d == 1 || w== 1){
ans++;
}
ans ++;
}
System.out.println(ans);
}
}
试题 E: 七段码
【问题描述】
小蓝可以用七段码数码管表达多少种不同的字符
【答案提交】
80
public class Q_E {
static int[] arr = {0, 1, 2, 3, 4, 5, 6};
public static void main(String[] args) {
int ans = 7;
ans += dfs(0,2)/2;
ans += dfs(0,3)/6;
ans += dfs(0,4)/24;
ans += dfs(0,5)/120;
ans += 7;
ans += 1;
System.out.println(ans);
}
//测出所以可能
private static int dfs(int index, int num) {
int count = 0;
if(index == num) {
if(check(num)) count ++;
}
for(int j = index;j<7;j++) {
{
int t = arr[j];
arr[j] = arr[index];
arr[index] = t;
}
count +=dfs(index +1,num);
{
int t = arr[j];
arr[j] = arr[index];
arr[index] = t;
}
}
return count;
}
//测试是否连通
private static boolean check(int num) {
int count = 0;
int[] check = new int[7];
for(int i = 0;i<num;i++) {
check[arr[i]] = 1;
}
for(int j = 0;j<7;j++) {
if(check[j] ==1) {
f(check,j);
count ++;
}
}
return count == 1;
}
private static void f(int[] check, int index) {
check[index] = 0;
if(index == 0) {
if(check[1] == 1) {
f(check,1);
}
if(check[5] == 1 ) {
f(check,5);
}
if(check[6] == 1) {
f(check,6);
}
}
if(index == 1) {
if(check[0] == 1) {
f(check,0);
}
if(check[2] == 1) {
f(check,2);
}
}
if(index == 2) {
if(check[1] == 1) {
f(check,1);
}
if(check[3] == 1 ) {
f(check,3);
}
if(check[6] == 1) {
f(check,6);
}
}
if(index == 3) {
if(check[2] == 1) {
f(check,2);
}
if(check[4] == 1 ) {
f(check,4);
}
if(check[6] == 1) {
f(check,6);
}
}
if(index == 4) {
if(check[3] == 1) {
f(check,3);
}
if(check[5] == 1 ) {
f(check,5);
}
}
if(index == 5) {
if(check[0] == 1) {
f(check,0);
}
if(check[4] == 1 ) {
f(check,4);
}
if(check[6] == 1) {
f(check,6);
}
}
if(index == 6) {
if(check[0] == 1) {
f(check,0);
}
if(check[2] == 1) {
f(check,2);
}
if(check[3] == 1) {
f(check,3);
}
if(check[5] == 1 ) {
f(check,5);
}
}
}
}
试题 F: 成绩统计
【问题描述】
小蓝给学生们组织了一场考试,总分100,学生的得分都是0-100的整数。
如果得分至少是60分,则称为及格。如果得分至少为85,则称为优秀。
请计算及格率和优秀率,用百分数表示,四舍五入。
【答案提交】
import java.util.Scanner;
public class Q_F {
public static void main(String[] args) {
int n, a, res = 0, ans = 0;
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for(int i = 1; i <= n; i++){
a = sc.nextInt();
if(a >= 60) res++;
if(a >= 85) ans++;
}
System.out.println(Math.round((double)res * 100.0 / n) + "%");
System.out.println(Math.round((double)ans * 100.0 / n) + "%");
}
}
试题 G: 回文日期
【问题描述】
给定一个八位数日期,计算该日期之后下一个回文日期和下一个ABABBABA型回文日期各是哪一天
【答案提交】
import java.util.*;
import java.text.SimpleDateFormat;
public class Q_G {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
String num = Integer.toString(n);
boolean condition1 = false, condition2 = false;
for (int i = n; !condition1 || !condition2; i += 10000) {
String date = Integer.toString(i);
StringBuffer sb = new StringBuffer(date.substring(0, 4));
String sb2 = sb.reverse().toString();
String string = sb.reverse().toString().concat(sb2);
if (!condition1 && isDate(string) && string.compareTo(num) > 0) {
System.out.println(string);
condition1 = true;
}
if (!condition2 && isDate(string) && string.compareTo(num) > 0 && string.substring(0, 2).equals(string.substring(2, 4))) {
System.out.println(string);
condition2 = true;
}
}
scan.close();
}
public static boolean isDate(String date) {
String dt = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
sdf.setLenient(false);
sdf.parse(dt);
} catch (Exception e) {
return false;
}
return true;
}
}
试题 H: 子串分值和
【问题描述】
给定一个字符串S,计算其分值和
【答案提交】
import java.util.Arrays;
import java.util.Scanner;
public class Q_H {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
char[] arr1 = scan.nextLine().toCharArray();
int[] arr2 = new int[26];
long count = 0;
int index;
long len = arr1.length;
Arrays.fill(arr2, -1);
for (int i = 0; i < arr1.length; i++) {
index = arr1[i] - 'a';
count += (len - i) * (i - arr2[index]);
arr2[index] = i;
}
System.out.println(count);
}
}
试题 I: 平面切分
【问题描述】
平面上有 N 条直线,请计算这些直线将平面分成了几个部分。
【答案提交】
这题不会写,附上别人C++的答案
#include <bits/stdc++.h>
using namespace std;
const int N = 1010, inf = 1e9 + 10;
int n, ans, a[N], b[N];
#define Point pair<double, double>
#define x first
#define y second
const Point INF = Point{inf, inf};
bool check(Point e1, Point e2) {
return (abs(e1.x - e2.x) <= 1e-2 && abs(e1.y - e2.y) <= 1e-2);
}
Point jd(int m, int n) { //求交点
double x1 = a[m], x2 = a[n], y1 = b[m], y2 = b[n];
//平行则无交点
if (x1 == x2) {
return INF;
}
Point cp = Point{};
cp.x = (y2 - y1) / (x1 - x2);
cp.y = (x1 * y2 - x2 * y1) / (x1 - x2);
return cp;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &a[i], &b[i]);
}
ans = 2; //初始一条直线可以划分为两个平面
for (int i = 2; i <= n; ++i) {
vector<Point> v;
bool f = 0;
for (int j = 1; j < i; ++j) {
// i 为新加入的点,与之前的点做划分,判断直线 i, j是否存在交点
Point now = jd(i, j);
if (check(now, INF)) {//直线 i, j不存在交点 continue
continue;
}
//直线i, j存在交点 去重
int len = v.size();
for (int k = 0; k < len; ++k) {
if (check(now, v[k])) {
f = 1;
}
}
if (!f) {
v.push_back(now);
}
}
ans += v.size() + 1;
}
printf("%d\n", ans);
return 0;
}
————————————————
版权声明:本文为CSDN博主「nuoyanli」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/nuoyanli/article/details/109138714
试题 J: 字串排序
【问题描述】
小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。
在冒泡排序中,每次只能交换相邻的两个元素。
小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,
则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串 lan 排序,只需要 1 次交换。对于字符串 qiao 排序,
总共需要 4 次交换。
小蓝的幸运数字是 V,他想找到一个只包含小写英文字母的字符串,对这
个串中的字符进行冒泡排序,正好需要 V 次交换。请帮助小蓝找一个这样的字
符串。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,
请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。
【答案提交】
import java.util.Scanner;
public class Q_I {
final static int N = (int)1e4 + 10;
static char[] ans = new char[N];
static char[] res = new char[N];
static int n, len;
public static void main(String[] args) {
len = 0x3f3f3f3f;
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
dfs(0,8,0,0);
for(int i = len; i >= 1; i--){
System.out.print(ans[i]);
}
}
public static boolean judge(){
int i = len;
while(ans[i] == res[i] && i != 0) i--;
return res[i] < ans[i];
}
public static void dfs(int now, int maxN, int m, int sum) {
if(sum == n){
if(m < len || (m == len && judge())){
len = m;
if (len >= 0) System.arraycopy(res, 1, ans, 1, len);
}
return;
}
if(now >= 26) return;
for(int i = 1; i <= maxN; i++){
int temp = sum + m * i;
if(temp > n) return;
res[m + i] = (char)(now + (int)'a');
dfs(now + 1, i, m + i, temp);
}
}
}