67-蓝桥省赛-2014

1.啤酒和饮料
啤酒每罐2.3元,饮料每罐1.9元。小明买了若干啤酒和饮料,一共花了82.3元。
我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。
思路:循环遍历,注意精度问题,将钱数乘10计算。

答案:11

用浮点数计算时有误差不能直接用==号来判断,可以通过控制误差来得到,在进行验算;

或者直接将价格,以及花的钱提高十倍,都化为整数计算;

//思路:循环遍历,注意精度问题,将钱数乘10计算。
#include <iostream>
#include <cmath>
using namespace std;

int main(){
	for(int i = 0; i <= (int)82.3/2.3; i++){
		sum = 0; 
		for(int j = 1; j <= (int)82.3/1.9; j++){
			if(abs(i * 2.3 + j * 1.9 - 82.3) < 0.0001){   //这里不能直接用==来判断,有误差!!! 
				cout << i << " " << j << endl;
				cout << 11 * 2.3 + 30 * 1.9 << endl; 
				return 0;  	
			} 
		}
	}
	
	return 0;
}
#include <iostream>  
  
using namespace std;  
  
int main(){  
    for(int i = 0; i < 40; ++i){  
        for(int j = 1; j < 43; ++j){  
            if(i > j)continue;  
            if(i * 23 + j * 19 == 823){  
                cout<<i<<" "<<j<<endl;  
            }  
        }  
    }  
    return 0;  
}  

  

2.李白打酒

话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。 
请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。
思路:dfs

答案:14

#include <bits/stdc++.h>
using namespace std;
int ct;

void dfs(string str, int d, int h, int sum){ //还需要遇到的次数:店家,花,剩余的酒 
	if(sum < 1 || d < 0  || h < 0){
		return ;
	}
	if(d == 0 && h == 0 && sum == 1){
		ct++;
		cout << str << endl;
		return ;
	} 
	dfs(str + "a", d - 1, h, 2 * sum);
	dfs(str + "b", d, h - 1, sum - 1);
}

int main(){
	string s;
	dfs(s, 5, 9, 2); //最后一次遇到花,相当于遇到花九次,剩余1升的酒;
	cout << ct << endl;
	return 0;
} 

 

3.切面条

一根高筋拉面,中间切一刀,可以得到2根面条。
如果先对折1次,中间切一刀,可以得到3根面条。
如果连续对折2次,中间切一刀,可以得到5根面条。
那么,连续对折10次,中间切一刀,会得到多少面条呢?
思路:
由于对折次数仅为10,数据规模并不大,可以通过手算简单的完成。
对折0次,得到2根;
对折1次,得到2 * 2 - 1 = 3
对折2次,得到3 * 2 - 1 = 5
对折3次,得到5 * 2 - 1 = 9
对折4次,得到9 * 2 - 1 = 17
对折5次,得到17 * 2 - 1 = 33
对折6次,得到33 * 2 - 1 = 65
对折7次,得到65 * 2 - 1 = 129
对折8次,得到129 * 2 - 1 = 257
对折9次,得到257 * 2 - 1 = 513
对折10次,得到513 * 2 - 1 = 1025

其实,上面的思路就是一种递归,可以把这种思想通过代码实现。
递归有基本递归与尾递归两种形式,本文分别进行了代码实现。
尾递归在一定程度上可以提高程序效率,通常比基本递归多一个参数。
递归的本质就是栈,当然可以用栈实现,在数据规模特别大的时候要显式的使用栈,以防止栈溢出。

答案:1025

思路:就是找规律,会发现所得的片段是对折折横的个数加上2.找个纸片看看。

而折痕的规律是,上一次得到的折痕加上上一次的层数为此次的折痕数,层数为:2的n-1次方,故折痕为: 1 + 2 + 4 + 8 + 16 + 2的9次方

最后加上2即可。

#include <iostream>
#include <sstream>
using namespace std;

int main(){
	int n;
	int sum = 1;
	int q = 1;
	for(int i = 1; i <= 9; i++){
		q *= 2;
		sum += q;
		cout << q << " ";
	}
	cout << endl;
	cout << sum  + 2 << endl;
	return 0;
}

  

史丰收速算
史丰收速算法的革命性贡献是:从高位算起,预测进位。不需要九九表,彻底颠覆了传统手算!
速算的核心基础是:1位数乘以多位数的乘法。
其中,乘以7是最复杂的,就以它为例。
因为,1/7 是个循环小数:0.142857...,如果多位数超过 142857...,就要进1
同理,2/7, 3/7, ... 6/7 也都是类似的循环小数,多位数超过 n/7,就要进n
下面的程序模拟了史丰收速算法中乘以7的运算过程。
乘以 7 的个位规律是:偶数乘以2,奇数乘以2再加5,都只取个位。
乘以 7 的进位规律是:
满 142857... 进1,
满 285714... 进2,
满 428571... 进3,
满 571428... 进4,
满 714285... 进5,
满 857142... 进6
请分析程序流程,填写划线部分缺少的代码。

答案:if(r>0)return i 

[cpp] view plain copy
 
    1. //计算个位   
    2. int ge_wei(int a)  
    3. {  
    4. if(a % 2 == 0)  
    5. return (a * 2) % 10;  
    6. else  
    7. return (a * 2 + 5) % 10;  
    8. }  
    9.   
    10. //计算进位   
    11. int jin_wei(char* p)  
    12. {  
    13. char* level[] = {  
    14. "142857",  
    15. "285714",  
    16. "428571",  
    17. "571428",  
    18. "714285",  
    19. "857142"  
    20. };  
    21.   
    22. char buf[7];  
    23. buf[6] = '';  
    24. strncpy(buf,p,6);  
    25.   
    26. int i;  
    27. for(i=5; i>=0; i--){  
    28. int r = strcmp(level[i], buf);  
    29. if(r<0) return i+1;  
    30. while(r==0){  
    31. p += 6;  
    32. strncpy(buf,p,6);  
    33. r = strcmp(level[i], buf);  
    34. if(r<0) return i+1;  
    35. ______________________________;  //填空  
    36. }  
    37. }  
    38.   
    39. return 0;  
    40. }  
    41.   
    42. //多位数乘以7  
    43. void f(char* s)   
    44. {  
    45. int head = jin_wei(s);  
    46. if(head > 0) printf("%d", head);  
    47.   
    48. char* p = s;  
    49. while(*p){  
    50. int a = (*p-'0');  
    51. int x = (ge_wei(a) + jin_wei(p+1)) % 10;  
    52. printf("%d",x);  
    53. p++;  
    54. }  
    55.   
    56. printf(" ");  
    57. }  
    58.   
    59. int main()  
    60. {  
    61. f("428571428571");  
    62. f("34553834937543");  
    63. return 0;  
    64. }  

5.打印图形
小明在X星球的城堡中发现了如下图形和文字:
rank=3
   * 
  * * 
 *   *  
* * * *
rank=5
               *                                                      
              * *                                                     
             *   *                                                    
            * * * *                                                   
           *       *                                                  
          * *     * *                                                 
         *   *   *   *                                                
        * * * * * * * *                                               
       *               *                                              
      * *             * *                                             
     *   *           *   *                                            
    * * * *         * * * *                                           
   *       *       *       *  
  * *     * *     * *     * *  
 *   *   *   *   *   *   *   * 
* * * * * * * * * * * * * * * *  
ran=6
                               *                                      
                              * *                                     
                             *   *                                    
                            * * * *                                   
                           *       *                                  
                          * *     * *                                 
                         *   *   *   *                                
                        * * * * * * * *                               
                       *               *                              
                      * *             * *                             
                     *   *           *   *                            
                    * * * *         * * * *                           
                   *       *       *       *                          
                  * *     * *     * *     * *                         
                 *   *   *   *   *   *   *   *                        
                * * * * * * * * * * * * * * * *                       
               *                               *                      
              * *                             * *                     
             *   *                           *   *                    
            * * * *                         * * * *                   
           *       *                       *       *                  
          * *     * *                     * *     * *                 
         *   *   *   *                   *   *   *   *                
        * * * * * * * *                 * * * * * * * *               
       *               *               *               *              
      * *             * *             * *             * *             
     *   *           *   *           *   *           *   *            
    * * * *         * * * *         * * * *         * * * *           
   *       *       *       *       *       *       *       *          
  * *     * *     * *     * *     * *     * *     * *     * *         
 *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *        
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *       
小明开动脑筋,编写了如下的程序,实现该图形的打印。

答案:f(a,rank-1,row, col + w/2)

//思路:就是先初始化一个矩阵,然后递归填值,每次递归下去都是在一个小矩阵中填值,每次固定的是
//矩阵的左上角,一次递归层数以及左上角坐标,注意没行的星号间是由空格的!! 
#include <iostream>
#include <cstdio> 
using namespace std;
#define N 70

void f(char a[][N], int rank, int row, int col)
{
	if(rank==1){
		a[row][col] = '*';
		return;
	}

	int w = 1;
	int i;
	for(i=0; i<rank-1; i++) 
		w *= 2;

    f(a, rank-1, row, col + w / 2)	;//填空  //最后一行是32 * 2个。故1/4 为 w/2 
	f(a, rank-1, row+w/2, col);
	f(a, rank-1, row+w/2, col+w);
}


int main()
{
	char a[N][N];
	int i,j;
	for(i=0;i<N;i++)
		for(j=0;j<N;j++) 
			a[i][j] = ' ';
	
	f(a,6,0,0);
	
	for(i=0; i<N; i++){
		for(j=0; j<N; j++) 
			printf("%c",a[i][j]);
		printf("
");
	}

	return 0;
}

  

7.六角填数 

如图所示六角形中,填入1~12的数字。
使得每条直线上的数字之和都相同。
图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?

思路:dfs


答案:10

 

#include <iostream>  
#include <cmath>  
#include <cstdio>  
#include <cstring>  
using namespace std;  
  
#define eps 10e-10  
#define N 15  
  
int a[N];  
bool vis[N];  
  
void dfs(int x){  
    if(x == 1 || x == 2 || x == 12){  
        dfs(x+1);  
        return ;  
    }  
    if(x > 12){  
        int t[6];  
        t[0] = a[1] + a[3] + a[6] + a[8];  
        t[1] = a[1] + a[4] + a[7] + a[11];  
        t[2] = a[2] + a[3] + a[4] + a[5];  
        t[3] = a[2] + a[6] + a[9] + a[12];  
        t[4] = a[8] + a[9] + a[10] + a[11];  
        t[5] = a[12] + a[10] + a[7] + a[5];  
          
        for(int i = 1; i < 6; ++i){  
            if(t[i] != t[i-1])return ;  
        }  
        cout<<a[6]<<endl;  
        return ;  
    }  
  
    for(int i = 1;i < 13; ++i){  
        if(!vis[i]){  
            vis[i] = 1;  
            a[x] = i;  
            dfs(x+1);  
            vis[i] = 0;  
        }  
    }  
  
  
}  
  
int main(){  
    memset(vis,0,sizeof(vis));  
    vis[1] = 1;  
    a[1] = 1;  
    vis[8] = 1;  
    a[2] = 8;  
    vis[3] = 1;  
    a[12] =3;  
  
    dfs(1);  
  
    return 0;  
}  

  暴力:

#include <iostream>
#include <algorithm>
using namespace std;
int a[9] = {2, 4, 5, 6, 7, 9, 10, 11, 12};
int x = 1, y = 3, z = 8;

int main()
{
	do{
		int d[10];
		 d[0] = 1 + a[0] + a[3] + a[5];
		 d[1] = 1 + a[1] + a[4] + a[8];
		 d[2] = 8 + a[0] + a[1] + a[2];
	  	 d[3] = 8 + a[3] + a[6] + 3;
		 d[4] = a[5] + a[6] + a[7] + a[8];
		 d[5] = 3 + a[7] + a[4] + a[2]; 
		int flag = 0;
		for(int i = 1; i <= 5; i++){
			if(d[i] != d[0]){
				flag = 1;
				break;
			}
		} 
		if(!flag)
			break;
	}while(next_permutation(a, a + 9));
	cout << a[3] << endl;
	
	return 0;
}

 

原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/8620894.html