2015 蓝桥杯省赛部分题整理(九数组分数,牌型种数,串逐位和,循环节长度,打印菱形)

简介: 2015 蓝桥杯省赛部分题整理(九数组分数,牌型种数,串逐位和,循环节长度,打印菱形)

1.九数组分数


题目描述:

1,2,3…9 这九个数字组成一个分数,其值恰好为1/3,如何组法?

下面的程序实现了该功能,请填写划线部分缺失的代码。


思路:不难看出这个程序在模拟全部数字的排列情况,用的是搜索与回溯算法,让每一位去与其后面的数字做交换,代码段缺少的部分正是回溯的部分,再做一次交换即可;


#include <stdio.h>
void test(int x[])
{
  int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
  int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];
  if(a*3==b) printf("%d / %d\n", a, b);
}
void f(int x[], int k)
{
  int i,t;
  if(k>=9){
  test(x);
  return;
  } 
  for(i=k; i<9; i++){
  {t=x[k]; x[k]=x[i]; x[i]=t;}
  f(x,k+1);
  _____________________________________________ // 填空处
  }
}
int main()
{
  int x[] = {1,2,3,4,5,6,7,8,9};
  f(x,0); 
  return 0;
}


答案:{t=x[k]; x[k]=x[i]; x[i]=t;}


2.牌型种数


题目描述:

小明被劫持到X赌城,被迫与其他3人玩牌。

一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。

这时,小明脑子里突然冒出一个问题:

如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?

输出:

能拿到的初始牌型组合数量;


思路:

一开始以为是一个组合数的问题,但是一直不知道怎么去除重复的部分,后来才知道就是一个暴力的搜索问题,在不考虑花色和顺序的情况下,只要考虑每个点数的张数即可,即用 每类四张的牌去组合成十三张牌看有多少种组合情况,可以用dfs来写,也可以写多重循环,这里只会给出多重循环的写法,对dfs有兴趣的可自行尝试;


代码


#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const ll maxx = 1e18;
const int N = 1e4+10;
const int p = 1e4;
const double eps = 1e-8;
int cnt;
int main()
{
  for(int i=0;i<=4;i++)//1 
  {
  for(int j=0;j<=4;j++)//2
  {
    for(int k=0;k<=4;k++)//3 
    {
    for(int l=0;l<=4;l++)//4 
    {
      for(int m=0;m<=4;m++)//5
      {
      for(int n=0;n<=4;n++)//6
      {
        for(int s=0;s<=4;s++)//7
        {
        for(int q=0;q<=4;q++)//8
        {
          for(int w=0;w<=4;w++)//9
          {
          for(int e=0;e<=4;e++)//10
          {
            for(int r=0;r<=4;r++)//11
            {
            for(int t=0;t<=4;t++)//12
            {
              for(int y=0;y<=4;y++)//13
              {
              if(i+j+k+l+m+n+s+q+w+e+r+t+y==13)
                cnt++;
              }  
            }  
            }  
          } 
          }
        } 
        } 
      } 
      } 
    }
    } 
  } 
  } 
  cout<<cnt;
}


答案:3598180;


3.串逐位和


描述:

给定一个由数字组成的字符串,我们希望得到它的各个数位的和。

比如:“368” 的诸位和是:17

这本来很容易,但为了充分发挥计算机多核的优势,小明设计了如下的方案:


int f(char s[], int begin, int end)
{
  int mid;
  if(end-begin==1) return s[begin] - '0';
  mid = (end+begin) / 2;
  return ____________________________________;  //填空
}
int main()
{
  char s[] = "4725873285783245723";
  printf("%d\n",f(s,0,strlen(s)));
  return 0;
}


思路:一个典型的分治思路;

就是把大的问题分解成子问题解决


一开始随便写了写,写的是


return f(s,begin,mid)+f(s,mid+1,end);


但是这是错的,用例子说明他为什么是错的


1.奇数长度串

111

(0,3) -> (0,1) 与 (2,3)

这样只能记录 第一个 1 和第三个 1,漏掉了第二个 1;

2.偶数长度串

1111

(0,4) -> (0,2) 与 (3,4) -> (0,1) 与 (1,2) 与 (3,4)

漏掉了第三个 1;


正确答案是:


return f(s,begin,mid)+f(s,mid,end);


1.奇数长度串

111

(0,3) -> (0,1) 与 (1,3) -> (0,1) 与 (1,2) 与 (2,3)

2.偶数长度串

1111

(0,4) -> (0,2) 与 (2,4) -> (0,1) 与 (1,2) 与 (2,3) 与 (3,4)

全部计算到;


所以正确答案就是


return f(s,begin,mid)+f(s,mid,end);


4.循环节长度


题目描述:

两个整数做除法,有时会产生循环小数,其循环部分称为:循环节。

比如,11/13=6=>0.846153846153… 其循环节为[846153] 共有6位。

下面的方法,可以求出循环节的长度。


请仔细阅读代码,并填写划线部分缺少的代码。


public static int f(int n, int m)
  {
  n = n % m;  
  Vector v = new Vector();
  for(;;)
  {
    v.add(n);
    n *= 10;
    n = n % m;
    if(n==0) return 0;
    if(v.indexOf(n)>=0)  _________________________________ ;  //填空
  }
  }


思路:

当循环中的任意两个位置的除数相等的时候其后的循环序列必然相等,有相同的的循环节就说明除数相等,去模拟整除并存入每一位的除数,找到相等的除数,两个相等除数之间的距离即为循环节长度。

注意这个题容易写成


return v.size();


这个错误答案,因为小数不一定是在小数点后就开始循环,比如1.2313313313…

我们要求的是两个相等除数之间的距离

故正确答案是:


return v.size() - v.indexOf(n);


5.打印菱形


描述:

给出菱形的边长,在控制台上打印出一个菱形来。

为了便于比对空格,我们把空格用句点代替。

当边长为8时,菱形为:


.......*
......*.*
.....*...*
....*.....*
...*.......*
..*.........*
.*...........*
*.............*
.*...........*
..*.........*
...*.......*
....*.....*
.....*...*
......*.*
.......*


下面的程序实现了这个功能,但想法有点奇怪。

请仔细分析代码,并填写划线部分缺失的代码。


public class A
{
  public static void f(int n)
  {
  String s = "*";
  for(int i=0; i<2*n-3; i++) s += ".";
  s += "*";
  String s1 = s + "\n";
  String s2 = "";
  for(int i=0; i<n-1; i++){
    //System.out.println("=>"+s);
    s = "." + _____________________________________ + "*";  //填空
    s1 = s + "\n" + s1;
    s2 += s + "\n";
  }
  System.out.println(s1+s2);  
  }
  public static void main(String[] args)
  {
  f(8);
  }
}



思路:虽然是一道Java的题,但还是看看思路,最后打印的是串

s1+s2 再看中间的操作过程,可以推出

s1是中间一行+上半部分

s2是中间一行+下半部分

循环过程就是累加过程

每次循环规律相同,我们举出一组循环来看

*.............* 到.*...........*

函数中给出了开头的".“和结尾的”*"我们只需要

把*.............*变成*...........

每次变换删去最后三个元素

结合Java string类型的函数就能推出答案是


s.substring(0,s.length()-3);


substring(first,last) 返回

[first,last]之间的字串


结语:


马山蓝桥杯了,蓝桥杯加油!!


目录
相关文章
|
4月前
|
存储 C语言
牛客网刷题总结(1.有序序列判断,2.获得月份天数,3.矩阵相等判定,4.矩阵转换,5.井字棋判断输赢,6.递归进行进制转化)
牛客网刷题总结(1.有序序列判断,2.获得月份天数,3.矩阵相等判定,4.矩阵转换,5.井字棋判断输赢,6.递归进行进制转化)
46 0
|
5天前
|
机器学习/深度学习 算法 测试技术
【组合数学 容斥原理 逆向思考】2930. 重新排列后包含指定子字符串的字符串数目
【组合数学 容斥原理 逆向思考】2930. 重新排列后包含指定子字符串的字符串数目
|
5月前
|
存储 算法
【LeetCode】每日一题&最后一个单词的长度&投票法求解多数元素&异或操作符巧解只出现一次的数字&整数反转
【LeetCode】每日一题&最后一个单词的长度&投票法求解多数元素&异或操作符巧解只出现一次的数字&整数反转
|
7月前
|
算法
【算法挨揍日记】day05——209. 长度最小的子数组、3. 无重复字符的最长子串
题目描述: 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
336 0
|
11月前
|
存储 机器学习/深度学习
母牛的故事 替换空格 二进制中1的个数 不使用第三个变量交换a,b的值
母牛的故事 替换空格 二进制中1的个数 不使用第三个变量交换a,b的值
68 0
|
11月前
剑指offer 19. 表示数值的字符串
剑指offer 19. 表示数值的字符串
29 0
|
11月前
|
算法
【基础算法】浅浅刷个小题 # 找不同 # 字符串中的单词数 # 重新排列字符串 #
【基础算法】浅浅刷个小题 # 找不同 # 字符串中的单词数 # 重新排列字符串 #
C语言经典实例:11-20例:使用结构体输出学生成绩、编制万年历、验证哥德巴赫猜想、求二维数组最大最小值、数组求素数、数组元素排序、进制数的转换进制数的转换、找出次大值、重组数组(下)
C语言经典实例:11-20例:使用结构体输出学生成绩、编制万年历、验证哥德巴赫猜想、求二维数组最大最小值、数组求素数、数组元素排序、进制数的转换进制数的转换、找出次大值、重组数组(下)
C语言经典实例:11-20例:使用结构体输出学生成绩、编制万年历、验证哥德巴赫猜想、求二维数组最大最小值、数组求素数、数组元素排序、进制数的转换进制数的转换、找出次大值、重组数组(下)
C语言经典实例:11-20例:使用结构体输出学生成绩、编制万年历、验证哥德巴赫猜想、求二维数组最大最小值、数组求素数、数组元素排序、进制数的转换进制数的转换、找出次大值、重组数组(上)
C语言经典实例:11-20例:使用结构体输出学生成绩、编制万年历、验证哥德巴赫猜想、求二维数组最大最小值、数组求素数、数组元素排序、进制数的转换进制数的转换、找出次大值、重组数组(上)
C语言经典实例:11-20例:使用结构体输出学生成绩、编制万年历、验证哥德巴赫猜想、求二维数组最大最小值、数组求素数、数组元素排序、进制数的转换进制数的转换、找出次大值、重组数组(上)
|
算法 Java 编译器
【算法】最后一个单词的长度,颠倒二进制位,排列序列等三道算法题目
最后一个单词的长度,颠倒二进制位,排列序列等三道算法题目
43 0