2015蓝桥杯省赛整理1-6

今天试着做了一下蓝桥杯的题,10个题做了4个只对了3个。我不知道以这样的水平去参加省赛会有多悲惨,但是我知道还有一个月的时间。加油~

【第1题】统计不含4的数字

题目大意:统计10000至99999中,不包含4的数值个数。

总结:
这个题很明显,很暴力地遍历就可以了。另外要注意是i=1到i<=99999。 我是写程序做的,但是写成了<99999于是答案少了1。挺可惜的。
从网上一些大神给出了另一种解法:最高位除了0、4不能使用,其余8个数字(1,2,3,5,6,7,8,9)均能使用,剩下的四位(千位、百位、十位、个位)可以使用除了4以外的所有数字,所以共有 8*9*9*9*9种解,计算得答案为:52488。是不是很对T_T我这脑子。


【第2题】计算1千天后的日期

题目大意:2014-11-09再过1000天是哪一日?

总结:
我觉得1000也不多嘛,然后就手算的,也不算慢。
然后看到了网上大神的解答,我直接服了...竟然是Execl! Excel其实是用一个实数来存储日期,这个实数的整数部分,就是1900年1月1日到当前日期的间隔天数,所以日期与整数间,可以直接做加减运算。真是上了一课,Excel功能也是蛮强大,听说有一道“高斯公式”也是用excel做的,今天还要整理真题,记得明天查一下。

【第3题】竖式加法

题目大意:题目用了8个不同的汉字,表示0~9里八种不同的数字。组成两个数值相加,等于第三个数值。  

   祥 瑞 生 辉 

   三 羊 献 瑞 

−————  
 三 羊 生 瑞 气 
总结:

这个题我是写程序做的,把m,n两个四位数拆分出来,做的比较艰难,因为漏了一个条件这几个字代表的数字互不相等。好在最后做出来了。

网上大神写的,复制来膜拜...定义一个数组int a[10],初始化用a[i]存储i。将a[2]~a[9]与各个汉字对应,然后用next_permutation全排列暴力解,注意三个数值开头不能为0,能解出第2个数值,即“三羊献瑞”对应的数字是1085。

 #include <cstdio>
 #include <algorithm>
using namespace std;

int main() {
    int a[10];
    for (int i = 0; i < 10; i++) a[i] = i;

    do {
        if (!a[2] || !a[6]) continue;
        int x =              a[2]*1000 + a[3]*100 + a[4]*10 + a[5];
        int y =              a[6]*1000 + a[7]*100 + a[8]*10 + a[3];
        int z = a[6]*10000 + a[7]*1000 + a[4]*100 + a[3]*10 + a[9];
        if (x + y == z) printf("%d + %d = %d\n", x, y, z);
    } while (next_permutation(a, a+10));

    return 0;
}

  当然,这题也可以用数学知识简单的推导出一部分数字后,再暴力解剩下的部分。

【第4题】古怪的星号修饰符

格子中输出
StringInGrid函数会在一个指定大小的格子中打印指定的字符串。
要求字符串在水平、垂直两个方向上都居中。
如果字符串太长,就截断。
如果不能恰好居中,可以稍稍偏左或者偏上一点。
下面的程序实现这个逻辑,请填写划线部分缺少的代码。

题目大意:

  是道代码填空题,主要是完成一个字符串s,按宽度width截断后,在固定宽度为width,两边为符号’|’的居中输出。 
  难点是题目给出了printf(“%*s%s%*s”,___),要求填printf的实参列表。

对于题目中数据,应该输出:
+------------------+
|            |
|   abcd1234    |
|             |
|             |
+------------------+
(如果出现对齐问题,参看【图1.jpg】)

#include <stdio.h>
#include <string.h>
void StringInGrid(int width, int height, const char* s)
{
int i,k;
char buf[1000];
strcpy(buf, s);
if(strlen(s)>width-2) buf[width-2]=0;

printf("+");
for(i=0;i<width-2;i++) printf("-");
printf("+\n");

for(k=1; k<(height-1)/2;k++){
printf("|");
for(i=0;i<width-2;i++) printf(" ");
printf("|\n");
}

printf("|");

printf("%*s%s%*s",_____________________________________________);  //填空
         
printf("|\n");

for(k=(height-1)/2+1; k<height-1; k++){
printf("|");
for(i=0;i<width-2;i++) printf(" ");
printf("|\n");
}

printf("+");
for(i=0;i<width-2;i++) printf("-");
printf("+\n");
}
int main()
{
StringInGrid(20,6,"abcd1234");
return 0;
}

网上找的...题解:

  简单还原现场及参考答案:

 #include <stdio.h>
 #include <string.h>

int main() 
{
    char s[100] = "abcd1234";
    char buf[1000];
    int width = 20;

    strcpy(buf, s);
    buf[width-2] = 0;

    printf("|%*s%s%*s|\n", (width-strlen(buf)-2)/2, "", buf, (width-strlen(buf)-2)/2, "");
    return 0;
}
总结:
很惭愧,本题没有思路,唯一能明白的是本题是打印出一个图形,居中输出;缺失代码的那一行很明显就是中间输出居中文字的那一行,但是我不知道%*s的意思,所以不知道怎么填。看了题解,在此总结一下:
1.scanf里用*修饰符,是起到过滤读入的作用。比如一个有三列数值的数据,我只想得到第2列数值,可以在循环里scanf(“%*d%d%*d”, a[i])来读入第i行的第2个数值到a[i]。 
2.* 修饰符在printf中的含义完全不同。printf(“%s”,6,“abc”)等价于printf(“%6d”, 123),这是设置域宽的意思。同理,%6s也是域宽。* 修饰符正是用来更灵活的控制域宽。使用%*s,表示这里的具体域宽值由后面的实参决定,如printf(“%*s”, 6, “abc”)就是把”abc”放到在域宽为6的空间中右对齐。因此,这里应该填写5个实参(每个%s一个,每个%*s两个)。然后字符长度的计算应该用buf而不是s,因为buf才是截断后的长度用s的话,如果s长度超过了width-2,效果就不对了。(还是不懂!)

【第五题】九数组分数
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);
_____________________________________________ // 填空处
}
}

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

总结:
  起初看到这个题先想到全遍历解决的,为什么一到代码填空就懵了,练得太少了...好吧,又不会,又是查的答案。 回溯法?什么东东?(不行,老妈开始催睡觉了,明天再继续总结吧^-^)/又是中午12点多了...唉,继续。

根据网上的资料,这个题的实质是【补充全排列的回溯算法】。其实这个题第3题一样可以用全排列暴力,但这题是代码填空题,且已经手写一部分全排列算法,我们负责补充其中一行代码。【写全排就是用回溯的思想】,直接猜到for循环里的第三行,应该就是把第一行的交换操作再交换回来~~复制for里的第一行代码,运行下程序,还不放心就调试下,看看数组是不是有按字典序在变化就行了。

 
  今天对回溯法了解了一点皮毛,通过资料了解到【五大常用算法】分治算法、动态规划算法、贪心算法、回溯法、分支界限法。接下来找一些题练一下。

【第6题】加号改乘号


题目大意

把1+2+3+…+48+49中的两个加号改成乘号(修改位置不能相邻),使得式子的结果由1225变为2015。

总结:
这个题思路很清晰,只要1225-i-i+1-j-j+1+i*i+1+j*j+1=2015,遍历就可以了。注意循环条件,j与i必须相隔一个数。
#include <stdio.h>

int main() {
    for (int i = 1; i <= 48; i++) {
        for (int j = i + 2; j <= 48; j++) {
            if (1225 - i - (i+1) - j - (j+1) == 
                2015 - i*(i+1) - j*(j+1))
                printf("%d\n", i);
        }
    }
    return 0;
}






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值