2017年比赛题总结

111111

1.购物单

小明刚刚找到 工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到 商场代为购物。小明很厌烦,但又不好推辞。 这不,XX 大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠的。 小明也有个怪癖,不到万不得已,从不刷卡,直接现金搞定。 现在小明很心烦,请你帮他计算一下,需要从取款机上取多少现金,才能搞定这次购物。 取款机只能提供 100 元面额的纸币。小明想尽可能少取些现金,够用就行了。 你的任务是计算出,小明最少需要取多少现金。

以下是让人头疼的购物单,为了保护隐私,物品名称被隐藏了。

**** 180.90 88 折
**** 10.25 65 折
**** 56.14 9 折
**** 104.65 9 折
**** 100.30 88 折
**** 297.15 半价
**** 26.75 65 折
**** 130.62 半价
**** 240.28 58 折
**** 270.62 8 折
**** 115.87 88 折
**** 247.34 95 折
**** 73.21 9 折
**** 101.00 半价
**** 79.54 半价
**** 278.44 7 折
**** 199.26 半价
**** 12.97 9 折
**** 166.30 78 折
**** 125.50 58 折
**** 84.98 9 折
**** 113.35 68 折
**** 166.57 半价
**** 42.56 9 折
**** 81.90 95 折
**** 131.78 8 折
**** 255.89 78 折
**** 109.17 9 折
**** 146.69 68 折
**** 139.33 65 折
**** 141.16 78 折
**** 154.74 8 折
**** 59.42 8 折
**** 85.44 68 折
**** 293.70 88 折
**** 261.79 65 折
**** 11.30 88 折
**** 268.27 58 折
**** 128.29 88 折
**** 251.03 8 折
**** 208.39 75 折
**** 128.88 75 折
**** 62.06 9 折
**** 225.87 75 折
**** 12.89 75 折
**** 34.28 75 折
**** 62.16 58 折
**** 129.12 半价
**** 218.37 半价
**** 289.69 8 折

需要说明的是,88 折指的是按标价的 88%计算,而 8 折是按 80%计算,余者类推。
特别地,半价是按 50%计算。
请提交小明要从取款机上提取的金额,单位是元。
答案是一个整数,类似 4300 的样子,结尾必然是 00,不要填写任何多余的内容。


答案:5200

自行把输入数据改一下即可

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
    double a,b,s=0;
    while(~scanf("%lf %lf",&a,&b))
    {
        if(a==0&&b==0)
            break;
        s+=a*b*0.01;
    }
    printf("%f\n",s);
    return 0;
}

2.等差素数列

2,3,5,7,11,13,…是素数序列。类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,
叫等差素数数列。上边的数列公差为 30,长度为 6。2004 年,格林与华人陶哲轩合作证明
了:存在任意长度的素数等差数列。这是数论领域一项惊人的成果!有这一理论为基础,
请你借助手中的计算机,满怀信心地搜索:长度为 10 的等差素数列,其公差最小值是多
少?注意:需要提交的是一个整数,不要填写任何多余的内容和说明文字。


答案:210

代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
int prime(int x)
{
    for(int i=2;i<=(int)sqrt(x);i++)
    {
        if(x%i==0)
            return 0;
    }
    return 1;
}
int main()
{
    for(int k=1;k<=500;k++)
    {
        for(int i=2;i<=10000;i++)
        {
            if(prime(i))
            {
                if(prime(i+k)&&prime(i+2*k)&&prime(i+3*k)&&prime(i+4*k)&&prime(i+5*k)&&prime(i+6*k)&&prime(i+7*k)&&prime(i+8*k)&&prime(i+9*k))
                {
                    printf("%d\n",k);
                }
            }
        }
    }
    return 0;
}

3.承压计算

X 星球的高科技实验室中整齐地堆放着某批珍贵金属原料。
每块金属原料的外形、尺寸完全一致,但重量不同。金属材料被严格地堆放成金字塔形。
7
5 8
7 8 8
9 2 7 2
8 1 4 9 1
8 1 8 8 4 1
7 9 6 1 4 5 4
5 6 5 5 6 9 5 6
5 5 4 7 9 3 5 5 1
7 5 7 9 7 4 7 3 3 1
4 6 4 5 5 8 8 3 2 4 3
1 1 3 3 1 6 6 5 5 4 4 2
9 9 9 2 1 9 1 9 2 9 5 7 9
4 3 3 7 7 9 3 6 1 3 8 8 3 7
3 6 8 1 5 3 9 5 8 3 8 1 8 3 3
8 3 2 3 3 5 5 8 5 4 2 8 6 7 6 9
8 1 8 1 8 4 6 2 2 1 7 9 4 2 3 3 4
2 8 4 2 2 9 9 2 8 3 4 9 6 3 9 4 6 9
7 9 7 4 9 7 6 6 2 8 9 4 1 8 1 7 2 1 6
9 2 8 6 4 2 7 9 5 4 1 2 5 1 7 3 9 8 3 3
5 2 1 6 7 9 3 2 8 9 5 5 6 6 6 2 1 8 7 9 9
6 7 1 8 8 7 5 3 6 5 4 7 3 4 6 7 8 1 3 2 7 4
2 2 6 3 5 3 4 9 2 4 5 7 6 6 3 2 7 2 4 8 5 5 4
7 4 4 5 8 3 3 8 1 8 6 3 2 1 6 2 6 4 6 3 8 2 9 6
1 2 4 1 3 3 5 3 4 9 6 3 8 6 5 9 1 5 3 2 6 8 8 5 3
2 2 7 9 3 3 2 8 6 9 8 4 4 9 5 8 2 6 3 4 8 4 9 3 8 8
7 7 7 9 7 5 2 7 9 2 5 1 9 2 6 5 3 9 3 5 7 3 5 4 2 8 9
7 7 6 6 8 7 5 5 8 2 4 7 7 4 7 2 6 9 2 1 8 2 9 8 5 7 3 6
5 9 4 5 5 7 5 5 6 3 5 3 9 5 8 9 5 4 1 2 6 1 4 3 5 3 2 4 1
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
其中的数字代表金属块的重量(计量单位较大)。
最下一层的 X 代表 30 台极高精度的电子秤。
假设每块原料的重量都十分精确地平均落在下方的两个金属块上,
最后,所有的金属块的重量都严格精确地平分落在最底层的电子秤上。
电子秤的计量单位很小,所以显示的数字很大。
工作人员发现,其中读数最小的电子秤的示数为:2086458231 请你推算出:读数最大的电
子秤的示数为多少?注意:需要提交的是一个整数,不要填写任何多余的内容。


答案:72665192664

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
double a[30][30]=
{
    {7},
	{5,8},
	{7,8,8},
	{9,2,7,2},
	{8,1,4,9,1},
	{8,1,8,8,4,1},
	{7,9,6,1,4,5,4},
	{5,6,5,5,6,9,5,6},
	{5,5,4,7,9,3,5,5,1},
	{7,5,7,9,7,4,7,3,3,1},
	{4,6,4,5,5,8,8,3,2,4,3},
	{1,1,3,3,1,6,6,5,5,4,4,2},
	{9,9,9,2,1,9,1,9,2,9,5,7,9},
	{4,3,3,7,7,9,3,6,1,3,8,8,3,7},
	{3,6,8,1,5,3,9,5,8,3,8,1,8,3,3},
	{8,3,2,3,3,5,5,8,5,4,2,8,6,7,6,9},
	{8,1,8,1,8,4,6,2,2,1,7,9,4,2,3,3,4},
	{2,8,4,2,2,9,9,2,8,3,4,9,6,3,9,4,6,9},
	{7,9,7,4,9,7,6,6,2,8,9,4,1,8,1,7,2,1,6},
	{9,2,8,6,4,2,7,9,5,4,1,2,5,1,7,3,9,8,3,3},
	{5,2,1,6,7,9,3,2,8,9,5,5,6,6,6,2,1,8,7,9,9},
	{6,7,1,8,8,7,5,3,6,5,4,7,3,4,6,7,8,1,3,2,7,4},
	{2,2,6,3,5,3,4,9,2,4,5,7,6,6,3,2,7,2,4,8,5,5,4},
	{7,4,4,5,8,3,3,8,1,8,6,3,2,1,6,2,6,4,6,3,8,2,9,6},
	{1,2,4,1,3,3,5,3,4,9,6,3,8,6,5,9,1,5,3,2,6,8,8,5,3},
	{2,2,7,9,3,3,2,8,6,9,8,4,4,9,5,8,2,6,3,4,8,4,9,3,8,8},
	{7,7,7,9,7,5,2,7,9,2,5,1,9,2,6,5,3,9,3,5,7,3,5,4,2,8,9},
	{7,7,6,6,8,7,5,5,8,2,4,7,7,4,7,2,6,9,2,1,8,2,9,8,5,7,3,6},
	{5,9,4,5,5,7,5,5,6,3,5,3,9,5,8,9,5,4,1,2,6,1,4,3,5,3,2,4,1}
};
int main()
{
    for(int i=1; i<=29; i++)
    {
        for(int j=0; j<=i; j++)
        {
            if(j==0)
                a[i][j]+=a[i-1][j]/2.0;
            else
                a[i][j]+=a[i-1][j-1]/2.0+a[i-1][j]/2.0;
        }
    }
    double minn=99999999;
    double maxx=0;
    for(int i=0;i<=29;i++)
    {
        if(a[29][i]<minn)
            minn=a[29][i];
        if(a[29][i]>maxx)
            maxx=a[29][i];
    }
    printf("%.0f\n",2086458231/minn*maxx);
    return 0;
}

4.方格分割

6x6 的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。
如图就是可行的分割法:可行的分割方式
试计算:
包括这 3 种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。
请提交该整数,不要填写任何多余的内容或说明文字。
在这里插入图片描述


答案:509

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int book[10][10];
int s=0;
void dfs(int x,int y)
{
    if(x==0||y==0||x==6||y==6)
    {
        s++;
        return ;
    }
    for(int i=0;i<4;i++)
    {
        int tx=x+dir[i][0];
        int ty=y+dir[i][1];
        int dx=6-tx;
        int dy=6-ty;
        if(tx>=0&&tx<=6&&ty>=0&&ty<=6)
        {
             if(!book[tx][ty])
             {
                 book[tx][ty]=1;
                 book[dx][dy]=1;
                 dfs(tx,ty);
                 book[tx][ty]=0;
                 book[dx][dy]=0;
             }
        }
    }
}
int main()
{
    memset(book,0,sizeof(book));
    book[3][3]=1;
    dfs(3,3);
    printf("%d\n",s/4);
    return 0;
}

5.取数位

求 1 个整数的第 k 位数字有很多种方法。
以下的方法就是一种。
对于题目中的测试数据,应该打印 5。
请仔细分析源码,并补充划线部分所缺少的代码。
注意:只提交缺失的代码,不要填写任何已有内容或说明性的文字。
// 求 x 用 10 进制表示时的数位长度
int len(int x){
if(x<10) return 1;
return len(x/10)+1;
}
// 取 x 的第 k 位数字
int f(int x, int k){
if(len(x)-k==0) return x%10;
return _____________________; //填空
}
int main()
{
int x = 23574;
printf("%d\n", f(x,3));
return 0;
}


答案:f(x/10,k)

6.最大公共子串

最大公共子串长度问题就是:求两个串的所有子串中能够匹配上的最大长度是多少。
比如:“abcdkkk” 和 “baabcdadabc”,
可以找到的最长的公共子串是"abcd",所以最大公共子串长度为 4。
下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。
请分析该解法的思路,并补全划线部分缺失的代码。
注意:只提交缺少的代码,不要提交已有的代码和符号。也不要提交说明性文字。
#include <stdio.h>
#include <string.h>
#define N 256
int f(const char* s1, const char* s2)
{
int a[N][N];
int len1 = strlen(s1);
int len2 = strlen(s2);
int i,j;
memset(a,0,sizeof(int)NN);
int max = 0;
for(i=1; i<=len1; i++){
for(j=1; j<=len2; j++){
if(s1[i-1]==s2[j-1]) {
a[i][j] = __________________________; //填空
if(a[i][j] > max) max = a[i][j];
}
}
}
return max;
}
int main()
{
printf("%d\n", f(“abcdkkk”, “baabcdadabc”));
return 0;
}


答案:a[i-1][j-1]+1;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值