蓝桥杯笔记

一、关于头文件

//万能头文件#include<bits/stdc++.h>

1、#include<cstring>: strlen,  strcmp,  strcat,  strcpy, memset ,substr

(1)memset(dp,0,sizeof(dp)); //一般用于给数组清零

函数原型: void  *memset(void  *s, int  ch, size_t  n);

(2)取子字符串 : substr(start [, length ])

2、#include<cmath>: double fabs()

3、#include<algorithm>: max, min, int  abs, swap, reverse, sort,

lower_bound( begin,end,num),  upper_bound( begin,end,num)

(1)reverse( v.begin() , v.end() )

(2)sort(start,end,排序方法) 

   在从小到大的排序数组中:先用sort排序,默认从小到大sort(a,a+10); // 第二个是最后一位要排序的地址的下一地址

#include<algorithm>

int main()  {

  int a[10]={9,6,3,8,5,2,7,4,1,0};

  for(int i=0;i<10;i++)

  cout<<a[i]<<endl;

  sort(a,a+10);}// 第二个是结束的地址(最后一位要排序的地址的下一地址

从大到小:sort(a,a+10,compare);

#include<algorithm>

bool compare(int a,int b)

{

return a>b;

}

int main()

{

int a[10]={9,6,3,8,5,2,7,4,1,0};

for(int i=0;i<10;i++)

cout<<a[i]<<endl;

sort(a,a+10,compare);//在这里就不需要对compare函数传入参数了,

//这是规则

(3)

lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

4、#include<stdlib.h>malloc()、rand()、free()、system()

二、题型

结果填空  题目描述一个具有确定解的问题。要求选手对问题的解填空。  不要求解题过程,不限制解题手段(可以使用任何开发语言或工具, 甚至是手工计算), 只要求填写最终的结果

解题

1.(1)关于日期:一般用Excel加手算,关于(闰年、平年)

(2)求数目:一般是现实的问题,买东西之类的,注意类型、精度

例子:啤酒每罐2.3元,饮料每罐1.9元。小明买了若干啤酒和饮料,一共花了82.3元。

我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。

思路:循环遍历,注意精度问题,!!将钱数乘10计算。

例子:

海盗比酒量 浮点数比较

有一群海盗(不多于20人),在船上比拼酒量。过程如下:打开一瓶酒,所有在场的人平分喝下,有几个人倒下了。再打开一瓶酒平分,又有倒下的,再次重复...... 直到开了第4瓶酒,坐着的已经所剩无几海盗船长也在其中。当第4瓶酒平分喝下后,大家都倒下了。

船长写到:“......昨天,我正好喝了一瓶.. 

请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人没倒下。

例如,有一种可能是:20,5,4,2,0

多个答案排列顺序不重要。

答案写在“解答.txt”中,不要写在这里!

参考答案:

18,9,3,2,0      (1分)

15,10,3,2,0     (2分)

20,5,4,2,0      (0分)

12,6,4,2,0      (2分)

问题的核心就是海盗船长正好喝了一瓶酒,假设每一轮中的人数为n,a,b,c,那么船长喝的酒就是1/n+1/a+1/b+1/c,如果结果为1,那么就可能是一组解,因为还要保证一些附加条件,首先要n>a>b>c,然后就是在判断1的时候,因为使用的double并不是一个分数,而是一个小数,所以精度肯定会下降,因此只要保证sum-1.0<0.0000001就可以了。或者通分(即分子,分母相等)

int main()

{

    int n,a,b,c;

    for(n=1;n<=20;n++)  {

       for(a=1;a<=20;a++)  {

           if(a<n)

           for(b=1;b<=20;b++)  {

              if(b<a)

              for(c=1;c<=20;c++) {

                  if(c<b) {

                     //double sum=1.0/n+1.0/a+1.0/b+1.0/c;

                     //if(abs(sum-1.0)<0.0000001)  或

                     if(n*a*b*c==a*b*c + n*b*c + n*a*c + n*a*b)  {

                         cout<<n<<' '<<a<<' '<<b<<' '<<c<<endl;    }

 

2、3

一般是:关于多个数相不相等:优先 && 或 ||加continue

例子:   

int a,b,c,d,e,f,g,h;

       for(a=1;a<=9;a++)

        for(b=0;b<=9;b++) {

             if(a!=b)

             for(c=0;c<=9;c++) {

                    if(c!=a&&c!=b)

                    for(d=0;d<=9;d++) {

                           if(d!=a&&d!=b&&d!=c)

                           for(e=1;e<=9;e++) {

                                  if( e!=a && e!=b && e!=c && e!=d)

                                  for( f=0; f<=9; f++) {

                                         if(f!=a && f!=b && f!=c && f!=d && f!=e)

                                         for(g=0; g<=9; g++) {

                                                if(g!=a && g!=b && g!=c && g!=d && g!=e && g!=f)

                                                for(h=0; h<=9; h++) {

                                                       if(h!=a && h!=b && h!=c && h!=d && h!=e && h!=f && h!=g && (1000*a+100*b+10*c+d+1000*e+100*f+10*g+b)==(10000*e+1000*f+100*c+10*b+h))

                                                       cout<<e<<' '<<f<<' '<<g<<' '<<b<<endl;

                                                }  

等差数列 Sn=[ n*( a1 + an ) ] /2   一般是1,2,3... 则为 n*(n+1) /2

 

代码填空题只填写空缺部分,不要填写完整句子。 不要写注释、说明 或其它题目中未要求的内容。所填代码应该具有通用性,不能只对 题面中给出的特殊示例有效。

解题

先直接粘贴代码,使其运行,观察运行结果

一般是动态规划其实也包括递归,对一个函数名或数组名做a[i+-1][j+-1]或其他变化; 回溯:互换后一般可能要换回

一些题目的答案:

14:(1)if(r>0)return i    (2) f(a,rank-1,row, col + w/2)

15:(1)(width-strlen(s)-2)/2,"",buf,(width-strlen(s)-1)/2,"" 

(2){t=x[k]; x[k]=x[i]; x[i]=t;}

16:(1)swap(a,p,j)  (2)f(a,k+1,m-i,b)

17:a[i][j]=a[i-1][j-1]+1    18: quick_select(a, i+1, r, k-(i-l+1))

动态规划:

数字三角形问题

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

从顶部向下走,每次只能走下面或者右下,走完全程,问你怎么走使得权值最大

dp【i】【j】:代表从第i行第j列出发得到的最优值

dp【i】【j】=maxdp【i+1】【j】,dp【i+1】【j+1】+a【i】【j】

 

编程大题      题目一般要用到标准输入和输出。  题目一般会给出示例数据。 一般题目的难度主要集中于对算法的设计和逻辑的组织上。  选手给出的解法应具有普遍性,不能只适用于题目的示例数据(当然,至少应该适用于题目的示例数据)。为了测试选手给出解法的性能,评分时用的测试用例可能包含大数据量的压力测试用例,选手选择算法时要尽可能考虑可行性和效率 问题

解题

一般第一道会简单。

枚举、搜索、模拟是蓝桥杯中数量最多的题目类别

//输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。

    // #include<iostream>

   // #include<stdio.h>

   // #include<string.h>

    #include<bits/stdc++.h>

    using namespace std;

    int main()

    {

       int i,r=0,max,lena,lenb;

       char s1[100],s2[100];

        int a[100],b[100];

        gets(s1);gets(s2);

       lena=strlen(s1);lenb=strlen(s2);

        for(i=0;i<lena;i++) a[i]=s1[lena-i-1]-'0';

        for(i=0;i<lenb;i++) b[i]=s2[lenb-i-1]-'0';//将s1,s2分别倒序赋给a,b(高精度加法是从末位开始往前加)

        if(lena>=lenb) max=lena;

        else max=lenb;

        if(lena>lenb) for(i=lenb;i<lena;i++) b[i]=0;

        if(lena<lenb) for(i=lena;i<lenb;i++) a[i]=0;//当a,b位数不同时,给位数少的赋0,保证后面的运算

        int c[102];

       

        for(i=0;i<max;i++)

       {   c[i]=r+a[i]+b[i];

           c[i]=c[i]%10;

           r=c[i]/10;

        }

       while(r!=0)

        {max++;

        c[max-1]=r%10;

        r=r/10;  

       }

        for(i=max-1;i>=0;i--)  cout<<c[i];

        cout<<endl;

    return 0;

}

进制转换:

// 十进制转十六进制 

 //思路:不断的取余(之前在纸上写的阶梯式算式,最后从下往上取数)

#include <iostream>

using namespace std;

int main()

{

   long long a;char s[10];int i=0,c=0,temp;//temp是int,s[]是char!!!

   cin>>a;

   if(a==0) cout<<0<<endl;       

   while(a!=0)

   {

      temp=a%16;c++;

      if(temp>=10) s[i++]=temp-10+'A';

      else s[i++]=temp+'0';//要看什么类型相加减,有int与char相加减,char会自动转成数字,输出的则看定义的是什么类型,再转化

      a=a/16;

   }

   for(i=c-1;i>=0;i--)  cout<<s[i];    

cout<<endl;

return 0;

}

// 十六进制转十进制

#include <iostream>

#include <stdio.h>

#include <string.h>

#include <cmath>

using namespace std;

int  main( )

{

   char a[8]; gets(a);

   int i,c=strlen(a);long long t=0;//注意输出的是否够空间     

   for(i=0;i<c;i++)

   {

   if(a[i]>='0'&&a[i]<='9') a[i]=a[i]-'0';//不能省,因为如果没有这步,当a[i]=0时,下面会转成48与之相乘

   else a[i]=10+(a[i]-'A');//字符型的比较要注意,注意必须是要用到才能写,不能提前写

                         //这里的if else 不能放在前面!!!

   t=t+a[i]*pow(16,c-i-1);

   }    

   cout<<t<<endl;

return 0;}

 

//十六进制转八进制

#include<iostream>

#include<cstring>

using namespace std;

 int main()

 { string s1,s2;//s1存输入的十六进制,s2存二进制

  int n; int i,j,k;

   cin>>n;

   for(i=0;i<n;i++)

   { cin>>s1; s2="";//对s2初始化

    for(j=0;j<s1.length();j++)

   { switch(s1[j])

    {    case '0':s2+="0000";break;

         case '1':s2+="0001";break;

         case '2':s2+="0010";break;

         case '3':s2+="0011";break;

         case '4':s2+="0100";break;

         case '5':s2+="0101";break;

         case '6':s2+="0110";break;

         case '7':s2+="0111";break;

         case '8':s2+="1000";break;

         case '9':s2+="1001";break;

         case 'A':s2+="1010";break;

         case 'B':s2+="1011";break;

         case 'C':s2+="1100";break;

         case 'D':s2+="1101";break;

         case 'E':s2+="1110";break;

         case 'F':s2+="1111";break;

         default:break; }

    }

         if(s2.length()%3==1)

         s2="00"+s2;

         if(s2.length()%3==2)

         s2="0"+s2;

         int flag=0;

         for(k=0;k<s2.length()-2;k+=3)

         { int p=4*(s2[k]-'0')+2*(s2[k+1]-'0')+s2[k+2]-'0';

         if(p) flag=1; //去掉前导,而且如果后面有0,那么前面已经使得 flag=1,所以能够输出

         if(flag) cout<<p; //如果只有 if(p) cout<<p;那么后面有0就输不出

         }

         cout<<endl;

  }

 return 0;

 }

注:

const int MAXN = 100005;

int a[MAXN],b[MAXN],c[MAXN];

int n,sum;

int main()    //当数组比较大时定义在main函数之外

return; 的作用相当于 break;  用于中断循环的作用,而 return 0; 则是return的另一种用法,专用于返回值非void的函数返回其值。

 

猜你喜欢

转载自blog.csdn.net/qq_42458302/article/details/92834897