2013年第四届蓝桥杯省赛试题及详解(Java本科C组)

蓝桥杯历年真题题目及题解目录汇总 

 

  1. 结果填空 (满分3分)
  2. 结果填空 (满分5分)
  3. 结果填空 (满分8分)
  4. 结果填空 (满分12分)
  5. 代码填空 (满分6分)
  6. 代码填空 (满分11分)
  7. 程序设计(满分4分)
  8. 程序设计(满分12分)
  9. 程序设计(满分15分)
  10. 程序设计(满分24分)

 

 

1.标题: 猜年龄


    美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。

    一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,他回答说:

    “我年龄的立方是个4位数。我年龄的4次方是个6位数。这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。”

    请你推算一下,他当时到底有多年轻。

    通过浏览器,直接提交他那时的年龄数字。
    注意:不要提交解答过程,或其它的说明文字。

18,这题完全不用把0-9这个限制条件敲到代码上,光是4位6位就筛剩几个数了,打印出来观察更快

public class _01_猜年龄1 {

	public static void main(String[] args) {
		for(int i=11;i<=150;i++) {
			int a = i*i*i;
			int b = i*i*i*i;
			if(a>=1000 && a<=9999 && b>=100000 && b<=999999)
				System.out.println(i+" "+a+" "+b);
		}
	}

}

2013年第四届蓝桥杯省赛试题及详解(Java本科C组)_第1张图片


2.标题: 组素数

    素数就是不能再进行等分的数。比如:2 3 5 7 11 等。
    9 = 3 * 3 说明它可以3等分,因而不是素数。

    我们国家在1949年建国。如果只给你 1 9 4 9 这4个数字卡片,可以随意摆放它们的先后顺序(但卡片不能倒着摆放啊,我们不是在脑筋急转弯!),那么,你能组成多少个4位的素数呢?

    比如:1949,4919 都符合要求。


请你提交:能组成的4位素数的个数,不要罗列这些素数!!

注意:不要提交解答过程,或其它的辅助说明文字。

我觉得可以先人工枚举全排,4!/2!=12个吧,比你写个全排函数快一些,而且普通的全排函数面对重复数字不能筛重,得出的是4!,所以人工完了之后就求素数个数吧答案:6 (1499,1949,4919,9419,9491,9941)

public class _02_组素数1 {

	public static void main(String[] args) {
		int[] a = new int[] {1499,1949,1994,9149,9194,9914,4199,4919,4991,9419,9491,9941};
		int ans=0;
		for(int i=0;i

也贴一下通过全排列的做法吧,多个步哈希查重

import java.util.HashSet;
import java.util.Set;

//素数判定、素数生成(筛法)、质因数分解
//有重复元素的全排列+检查
public class _02组素数 {

  /**
   * 处理从k开始的排列
   * @param arr
   * @param k
   */
  static void f(int[] arr, int k) {
    if (k == 4)//前面都已确定
      check(arr);

    for (int i = k; i < 4; i++) {
      //交换
      int t = arr[k];
      arr[k] = arr[i];
      arr[i] = t;

      f(arr, k + 1);

      t = arr[k];
      arr[k] = arr[i];
      arr[i] = t;
    }
  }

  static Set set = new HashSet();

  private static void check(int[] arr) {
    int x = arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3];
    boolean flag = true;
    for (int i = 2; i <= Math.sqrt(x); i++) {
      if (x % i == 0) {
        flag = false;
        System.out.println(x+" false");
        break;
      }
    }
    if (flag) {
      set.add(x);
      System.out.println(x+" true");
    }
  }

  public static void main(String[] args) {
    int[] arr = {1, 4, 9, 9};
    f(arr, 0);
    System.out.println(set.size());
  }
}


3.标题: 马虎的算式


    小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。

    有一次,老师出的题目是:36 x 495 = ?

    他却给抄成了:396 x 45 = ?

    但结果却很戏剧性,他的答案竟然是对的!!

    因为 36 * 495 = 396 * 45 = 17820

    类似这样的巧合情况可能还有很多,比如:27 * 594 = 297 * 54

    假设 a b c d e 代表1~9不同的5个数字(注意是各不相同的数字,且不含0)

    能满足形如: ab * cde = adb * ce 这样的算式一共有多少种呢?


请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。

满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。


答案直接通过浏览器提交。
注意:只提交一个表示最终统计种类数的数字,不要提交解答过程或其它多余的内容。

142,暴力到没朋友,填空题暴力枚举就好

import java.util.Scanner;
 
public class _02_马虎的算式1 {
 
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int ans=0;
		for(int a=1;a<=9;a++)
			for(int b=1;b<=9;b++) {
				if(b==a)
					continue;
				for(int c=1;c<=9;c++) {
					if(c==a || c==b)
						continue;
					for(int d=1;d<=9;d++) {
						if(d==a || d==b || d==c)
							continue;
						for(int e=1;e<=9;e++) {
							if(e==a || e==b || e==c || e==d)
								continue;
							if((10*a+b)*(100*c+10*d+e)==(100*a+10*d+b)*(10*c+e))//ab * cde = adb * ce
								ans++;
						}			
					}
				}
			}
		
		System.out.println(ans);	
	}
}

 


4.标题: 第39级台阶

    小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!

    站在台阶前,他突然又想着一个问题:

    如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?


    请你利用计算机的优势,帮助小明寻找答案。

要求提交的是一个整数。
注意:不要提交解答过程,或其它的辅助说明文字。

答案:51167078,一定要走偶数步?那不如一次就递归2步把,2步合成一步

public class _04第39级台阶1 {

	public static void main(String[] args) {
		System.out.println(f(39));
	}
	
	static int f(int x) {
		if(x==0)
			return 1;
		if(x<0)
			return 0;
		return f(x-2)+2*f(x-3)+f(x-4);//左脚1步右脚2步和右脚1步左脚2步不一样的哦
	}

}

 


5.标题:有理数类

    有理数就是可以表示为两个整数的比值的数字。一般情况下,我们用近似的小数表示。但有些时候,不允许出现误差,必须用两个整数来表示一个有理数。

    这时,我们可以建立一个“有理数类”,下面的代码初步实现了这个目标。为了简明,它只提供了加法和乘法运算。

class Rational
{
    private long ra;
    private long rb;
    
    private long gcd(long a, long b){
        if(b==0) return a;
        return gcd(b,a%b);
    }
    public Rational(long a, long b){
        ra = a;
        rb = b;    
        long k = gcd(ra,rb);
        if(k>1){ //需要约分
            ra /= k;  
            rb /= k;
        }
    }
    // 加法
    public Rational add(Rational x){
        return ________________________________________;  //填空位置
    }
    // 乘法
    public Rational mul(Rational x){
        return new Rational(ra*x.ra, rb*x.rb);
    }
    public String toString(){
        if(rb==1) return "" + ra;
        return ra + "/" + rb;
    }
}

使用该类的示例:
    Rational a = new Rational(1,3);
    Rational b = new Rational(1,6);
    Rational c = a.add(b);
    System.out.println(a + "+" + b + "=" + c);


请分析代码逻辑,并推测划线处的代码,通过网页提交
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!

数学通分:a/b + c/d = (a*d+b*c)/(b*d)

  • new Rational(ra*x.rb+rb*x.ra, rb*x.rb)
  • new Rational(this.ra * x.rb + x.ra * this.rb, this.rb * x.rb)

上面的答案都行,不要this是观察到乘法函数也没写

 


6.标题:逆波兰表达式

    正常的表达式称为中缀表达式,运算符在中间,主要是给人阅读的,机器求解并不方便。

    例如:3 + 5 * (2 + 6) - 1

    而且,常常需要用括号来改变运算次序。

    相反,如果使用逆波兰表达式(前缀表达式)表示,上面的算式则表示为:

    - + 3 * 5 + 2 6 1

    不再需要括号,机器可以用递归的方法很方便地求解。

    为了简便,我们假设:

    1. 只有 + - * 三种运算符
    2. 每个运算数都是一个小于10的非负整数
    
    下面的程序对一个逆波兰表示串进行求值。
    其返回值为一个数组:其中第一元素表示求值结果,第二个元素表示它已解析的字符数。

 

    static int[] evaluate(String x)
    {
        if(x.length()==0) return new int[] {0,0};
        
        char c = x.charAt(0);
        if(c>='0' && c<='9') return new int[] {c-'0',1};
        
        int[] v1 = evaluate(x.substring(1));
        int[] v2 = __________________________________________;  //填空位置
        
        int v = Integer.MAX_VALUE;
        if(c=='+') v = v1[0] + v2[0];
        if(c=='*') v = v1[0] * v2[0];
        if(c=='-') v = v1[0] - v2[0];
        
        return new int[] {v,1+v1[1]+v2[1]};
    }


    

请分析代码逻辑,并推测划线处的代码,通过网页提交。
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!

evaluate(x.substring(1+v1[1])),不会就试到会?样例自己弄简单的套

结构应该是这样的:

(操作符占的长度,如果从大的整体看一次长度只能为1)(v1占的长度)(剩下不就是v2占的长度,为v1+1剩下部分)

 


7.标题:核桃的数量

    小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。他的要求是:

    1. 各组的核桃数量必须相同
    2. 各组内必须能平分核桃(当然是不能打碎的)
    3. 尽量提供满足1,2条件的最小数量(节约闹革命嘛)

程序从标准输入读入:
a b c
a,b,c都是正整数,表示每个组正在加班的人数,用空格分开(a,b,c<30)

程序输出:
一个正整数,表示每袋核桃的数量。

例如:
用户输入:
2 4 5

程序输出:
20

再例如:
用户输入:
3 1 1

程序输出:
3

资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗  < 1000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

  题目的意思是求3个数的最小公倍数,了解下简单数论,扩展欧几里得,同余定理,
对于gcd,lcm 都可以通过先写2个数的,在套用2个数的求n个数的,和数学的思想一致,先求出2个数的最小公倍数再求3个数的

import java.util.Scanner;

public class _07核桃的数量1 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		System.out.println(lcm(in.nextInt(),in.nextInt(),in.nextInt()));
	}
	
	static int gcd(int a,int b) {
		if(b==0)
			return a;
		return gcd(b,a%b);
	}
	
	static int gcd(int a,int b,int c) {
		return gcd(gcd(a,b),c);
	}
	
	static int lcm(int a,int b) {
		return a*b/gcd(a,b);
	}
	
	static int lcm(int a,int b,int c) {
		int s = lcm(a,b);
		return s*c/gcd(s,c);
	}

}

 


8.标题:打印十字图

    小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示(可参见p1.jpg)

                     $$$$$$$$$$$$$
                     $           $
                   $$$ $$$$$$$$$ $$$
                   $   $       $   $
                   $ $$$ $$$$$ $$$ $
                   $ $   $   $   $ $
                   $ $ $$$ $ $$$ $ $
                   $ $ $   $   $ $ $
                   $ $ $ $$$$$ $ $ $
                   $ $ $   $   $ $ $
                   $ $ $$$ $ $$$ $ $
                   $ $   $   $   $ $
                   $ $$$ $$$$$ $$$ $
                   $   $       $   $
                   $$$ $$$$$$$$$ $$$
                     $           $
                     $$$$$$$$$$$$$


    对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并能任意控制层数。
    
    为了能准确比对空白的数量,程序要求对行中的空白以句点(.)代替。

输入格式:
一个正整数 n (n<30) 表示要求打印图形的层数

输出:
对应包围层数的该标志。

例如:
用户输入:
1
程序应该输出:
..$$$$$..
..$...$..
$$$.$.$$$
$...$...$
$.$$$$$.$
$...$...$
$$$.$.$$$
..$...$..
..$$$$$..

再例如:
用户输入:
3
程序应该输出:
..$$$$$$$$$$$$$..
..$...........$..
$$$.$$$$$$$$$.$$$
$...$.......$...$
$.$$$.$$$$$.$$$.$
$.$...$...$...$.$
$.$.$$$.$.$$$.$.$
$.$.$...$...$.$.$
$.$.$.$$$$$.$.$.$
$.$.$...$...$.$.$
$.$.$$$.$.$$$.$.$
$.$...$...$...$.$
$.$$$.$$$$$.$$$.$
$...$.......$...$
$$$.$$$$$$$$$.$$$
..$...........$..
..$$$$$$$$$$$$$..

请仔细观察样例,尤其要注意句点的数量和输出位置。


资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗  < 1000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

  

2013年第四届蓝桥杯省赛试题及详解(Java本科C组)_第2张图片

说实话,看见这种打印的题目就不想做了

import java.util.Scanner;
//2013-C-C第八题一样的
public class _08打印十字图 {

  static int N, L = 0, R;
  static char[][] arr;

  static void deal(int n) {
    //n=3,总宽17,最大下标16
    int l,r;
    l= (N-n)*2;//最小下标
    r=l+9+4*(n-1)-1;//最大下标
    for (int i = l+2; i <= r-2; i++) {
      arr[l][i] = '$';
      arr[r][i] = '$';
    }

    arr[l+1][l+2] = '$';
    arr[l+1][r-2] = '$';
    arr[r-1][l+2] = '$';
    arr[r-1][r-2] = '$';

    for (int i = l; i < l+3; i++) {
      arr[l+2][i] = '$';
      arr[r - 2][i] = '$';

    }
    for (int i = r; i >r-3 ; i--) {
      arr[l+2][i] = '$';
      arr[r - 2][i] = '$';
    }

    for (int i = l+3; i <= r-3; i++) {
      arr[i][l] = '$';
      arr[i][r] = '$';
    }
  }

  static void printAll() {
    for (int i = 0; i <= R; i++) {
      for (int j = 0; j <= R; j++) {
        if (arr[i][j] != '$') arr[i][j] = '.';
        System.out.print(arr[i][j]);
      }
      System.out.println();
    }
  }

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    N = sc.nextInt();
    R = 9 + 4 * (N - 1) - 1;//最大下标
    arr = new char[R+1][R+1];
    for (int i = N; i >=1 ; i--) {
      deal(i);
    }
    int c_i=2*N+2;
    int c_j=2*N+2;
    arr[c_i][c_j]='$';
    for (int i = c_i-2; i < c_i+3; i++) {
      arr[c_i][i]='$';
    }
    for (int i = c_i-2; i < c_i+3; i++) {
      arr[i][c_j]='$';
    }
    printAll();
  }

}


9.标题:买不到的数目

    小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。

    小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。

    你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。

    本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。

输入:
两个正整数,表示每种包装中糖的颗数(都不多于1000)

要求输出:
一个正整数,表示最大不能买到的糖数

不需要考虑无解的情况

例如:
用户输入:
4 7
程序应该输出:
17

再例如:
用户输入:
3 5
程序应该输出:
7

 
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗  < 3000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

  这题有个数学公式秒杀 a*b-(a+b),正常人想不到可以通过暴力枚举捞点分,甚至AC

public class _09买不到的数目 {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int a = sc.nextInt();
    int b = sc.nextInt();
    // System.out.println(a*b-a-b);

    int max = a * b;
    Set ss = new HashSet();
    //从0开始枚举到max
    for (int x = 0; a * x < max; x++) {
      for (int y = 0; a * x + b * y < max; y++) {
        ss.add(a * x + b * y);//用不小于0的x和y与系数能组合出来的数加入set中
      }
    }
    for (int i = max - 1; i >= 0; i--) {
      if (!ss.contains(i)) { //查找第一个不在set中的值
        System.out.println(i);
        break;
      }
    }
  }
}


10.标题:剪格子

    如图p1.jpg所示,3 x 3 的格子中填写了一些整数。

    我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60。

    本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
    如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。   
    如果无法分割,则输出 0

程序输入输出格式要求:
程序先读入两个整数 m n 用空格分割 (m,n<10)
表示表格的宽度和高度
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000
程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目。


例如:
用户输入:
3 3
10 1 52
20 30 1
1 2 3

则程序输出:
3

再例如:
用户输入:
4 3
1 1 1 1
1 30 80 2
1 1 1 100

则程序输出:
10

(参见p2.jpg)


资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗  < 5000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

左边图1,右边图2

  2013年第四届蓝桥杯省赛试题及详解(Java本科C组)_第3张图片2013年第四届蓝桥杯省赛试题及详解(Java本科C组)_第4张图片

思路和普通的dfs搜索+回溯一样,只是这里有个坑,可能会剪成3块,搜出答案的时候,先把和第一个连接的答案存起来,然后用一次dfs求联通块判断,最后别忘了 把求联通块时标记的vis复原,所以考虑到这个就不用boolean数组标记了,改成int,灵活 

import java.util.Scanner;

public class _09剪格子 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		m = in.nextInt();
		n = in.nextInt();
		a = new int[n][m];
		vis = new int[n][m];
		
		for(int i=0;isum/2 || t>ans)//稍微剪剪枝
			return;
		for(int i=0;i<4;i++) {
			int j = x + dx[i];
			int k = y + dy[i];
			if(ok(j,k)) {
				vis[j][k] = 1;
				dfs(j,k,now+a[j][k],t+1);
				vis[j][k] = 0;
			}
		}
	}
	
	static void init() {
		for(int i=0;i=0 && x=0 && y=0 && j=0 && k

贴一贴官方的c++代码

//
//  Created by zhengwei .
//  Copyright © 2019 lanqiao. All rights reserved.
//
/*
 
 标题:剪格子
 
 如图p1.jpg所示,3 x 3 的格子中填写了一些整数。
 
 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60。
 
 本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
 如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
 如果无法分割,则输出 0
 
 程序输入输出格式要求:
 程序先读入两个整数 m n 用空格分割 (m,n<10)
 表示表格的宽度和高度
 接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000
 程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目。
 
 
 例如:
 用户输入:
3 3
10 1 52
20 30 1
1 2 3
 
则程序输出:
3
 
 再例如:
 用户输入:
4 3
1 1 1 1
1 30 80 2
1 1 1 100
 
 则程序输出:
 10
 
 (参见p2.jpg)
 
 
 资源约定:
 峰值内存消耗 < 64M
 CPU消耗  < 5000ms
 
 
 请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
 
 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
 
 注意: main函数需要返回0
 注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
 注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。
 
 提交时,注意选择所期望的编译器类型。
 
 */
#include 
#include 
#include 
#include 
#define mk(i,j) make_pair(i,j)
using namespace std;

int m, n;
int total;
int g[10][10];
int ans;
/*抽象了一种剪辑方法*/
class Cut {
public:
    set > grids;//包含若干格子
    int sum;//所有格子的数值的求和
};
/**
 * 将st中的元素拷贝到新set中
 * @param st
 * @return
 */
set > copySet(set > &st) {
    set >::iterator iter = st.begin();
    set > ans;
    while (iter != st.end()) {
//        重新mkpair,加入新set中
        ans.insert(*iter);
        iter++;
    }
    return ans;
}
void add(int sum, int i, int j, set > &grids, Cut *&cut_new) {
    const pair &pair_n = make_pair(i , j);
//                    深度拷贝set
    set > grids_copy=copySet(grids);
    grids_copy.insert(pair_n);
    cut_new->grids=grids_copy;
    cut_new->sum=sum+g[i][j];
}
vector vs[100];//分别存储格子数为1~100的各种剪法

int main(int argc, const char *argv[]) {
    scanf("%d %d", &m, &n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            scanf("%d", &g[i][j]);
            total += g[i][j];
        }
    }
//    第一个格子就是一半
    if (g[0][0] == total / 2) {
        printf("%d\n", 1);
        return 0;
    }

    /*左上角格子,只有一种剪法,加入v[1]*/
    Cut *c = new Cut();
    const pair p = make_pair(0, 0);
    c->grids.insert(p);
    c->sum = g[0][0];
    vs[1].push_back(c);//只包含一个格子且包含00的只有一种剪法

    for (int i = 2; i <= m * n; ++i) {
//        i是格子数,用vs[i-1]里面的来生成
//迭代vs[i-1]里面的所有剪法
        for (int j = 0; j < vs[i - 1].size(); ++j) {
//            pCut代表一种剪辑方法
            Cut *pCut = vs[i - 1][j];
//            这种剪辑方法里面记录了所有格子,这些格子每个都扩展一个,即形成个数+1的剪法
            set > &grids = pCut->grids;
            int sum = pCut->sum;
            set >::iterator iter = grids.begin();
//            迭代所有的格子,尝试添加它的邻居
            while (iter != grids.end()) {
                const pair &p = *iter;//代表一个格子的坐标
                int x=p.first;
                int y=p.second;

                if(x+1sum==total/2){
                        printf("%d\n", i);
                        return 0;
                    }else if(cut_new->sum=0&&grids.find(mk(x-1,y))==grids.end()){//上方
                    Cut *cut_new=new Cut();
                    add(sum, x-1, y, grids, cut_new);
                    if(cut_new->sum==total/2){
                        printf("%d\n", i);
                        return 0;
                    }else if(cut_new->sumsum==total/2){
                        printf("%d\n", i);
                        return 0;
                    } else if(cut_new->sum=0&&grids.find(mk(x,y-1))==grids.end()){//左方
                    Cut *cut_new=new Cut();
                    add(sum, x, y-1, grids, cut_new);
                    if(cut_new->sum==total/2){
                        printf("%d\n", i);
                        return 0;
                    }else if(cut_new->sum

 

小结 

01 猜年龄 简单枚举
02 组素数 带重复元素的全排列+素数判定,用到set去重
03 马虎的算式 枚举5个变量,组合后,进行检查
*04 第39级台阶 走楼梯的一个变形,记录走的步数,本质是递归思维
05 有理数类 面向对象和分数加法(通分和约分)
*06 逆波兰表达式 递归的整体思维
07 核桃的数量 简单枚举
08 打印十字图 先写死,再变活
**09 买不到的数目  数学
**10 剪格子 深搜+回溯+剪枝

搜索(枚举=迭代和递归,dfs(含回溯和剪枝)、bfs、二分查找)
模拟

你可能感兴趣的:(蓝桥杯)