• 2020-02-07 蓝桥杯模拟赛1 F&H


    F. 试题F:你好,2020 15'

    描述

    2020年,这个年份很特别,2020从中间分成两个整数,大小形状完全一样。

    wlxsq对形如2020的数字很感兴趣(不包括前导零),在11200中这样的数字包括11、22、3344、55、66、77、88、99、1010、1111,共11个,他们的和是2616

    请问,在1n中,所有这样的数的和是多少?

    输入

    输入一行包含一个整数n

    输出

    输出一行,包含一个整数,表示满足条件的数的和。

    样例

    输入

    1200

    输出

    2616

    提示

    【评测用例规模与约定】

    对于20%的评测用例,1 ≤ n ≤ 100。

    对于50%的评测用例,1 ≤ n ≤ 10^3。

    对于80%的评测用例,1 ≤ n ≤ 10^4。

    对于100%的评测用例,1 ≤ n ≤ 10^6。

    //代码1
    #include<stdio.h>
    int main(){
        long i,n,sum;
        scanf("%d", &n);
        sum=0;
        for (i=1;i<=n;i++){
            if(10<=i&&i<100){
                if(i/10==i%10) sum+=i;
            }
            if(1000<=i&&i<10000){
                if(i/100==i%100) sum+=i;
            }
            if(100000<=i&&i<1000000){
                if(i/1000==i%1000) sum+=i;
            }
        }
        printf("%d",sum);
        return 0;
    }
    //代码2
    #include<stdio.h>
    using namespace std;
    #include<iostream>
    #define debug(x) cerr<<#x<<" "<<x<<endl;
    int n,A,B,a[20],p10[20]={1,10,100,1000,10000,100000,1000000};
    int split(int x){
        int cnt=0,res=0;
        for(;x;x/=10) a[++cnt]=x%10;
        int cct=cnt+1>>1;
        if(cnt&1){
            for(int i=cnt/2;i;i--) res=res*10+9;
            return res;
        }
        for(int i=cnt;i>cct;i--) A=A*10+a[i];
        for(int i=cct;i;i--) B=B*10+a[i];
        if(A<=B) return A;else return A-1;
    }
    int deal(int x){
        int cnt=0,t=x;
        for(;x;x/=10) a[++cnt]=x%10;
        return t*p10[cnt]+t;
    }
    long long ans;
    int main(){
        cin>>n;
        int sz=split(n);
        for(int i=1;i<=sz;i++) ans+=deal(i);
        cout<<ans;
        return 0;
    }

    H. 试题H:计算器 22'

    描述

    我们知道,windows自带calc功能。

    wlxsq决定制作一个Calc,该Calc具备求解一元一次方程的功能。

    为了简化工作,拒绝花里胡哨。这个方程中,只有一个等号"=",零个或多个加号"+"、减号"-",一种小写字母表示未知数。当然,减号也可是负号

    方程中并没有括号,也没有除号,方程中的字母表示未知数。

    输入

    仅一行,表示一个合法的方程,包含“+”、“-”、“=”、数字及小写字母。

    输出

    仅一行,表示答案,形式为“未知元=答案”。对答案保留3位小数,保证答案的绝对值不超过10000。

    样例

    输入

    2a=1

    输出

    a=0.500

    输入

    -5+2x=-10

    输出

    x=-2.500

    提示

    【评测用例规模与约定】

    对于20%的数据,输入数据没有"+,-"符号

    对于100%数据,长度不超过255,数字不超过10000,保证只出现一种小写字母。

    //代码1 
    #include<stdio.h>
    #include<string.h>
    #include<sstream>
    #include<iostream>
    using namespace std;
    #define debug(x) cerr<<#x<<" "<<x<<endl;
    string s,A,B;int a[5];char wz;bool cf;
    int getc(string &str,int len){
        for(int i=0;i<len;i++) if(isalpha(str[i])) return str[i];
        return -1;
    }
    void del(string &str,int l,int r){
        int i;
        for(i=r-1;i>=l;i--) if(!isdigit(str[i])) break;
        int num=0,f=1;
        if(i>=0){
            if(str[i]=='-') f=-1;else if(isdigit(str[i])) num=str[i]-'0';
        }
        for(int j=i+1;j<r;j++) num=num*10+str[j]-'0';
        if(!num&&(!r||!isdigit(str[r-1]))) num=1;
        num*=f;
        a[1]+=num;
        int li=i<0?0:i; int sz=r-li+1;
        str.erase(li,sz);
    }
    bool read(char *&s,int &x){
        bool f=0;x=0;
        for(;*s<'0'||*s>'9';*s++) if(*s=='-') f=1;
        for(;*s>='0'&&*s<='9';*s++) x=(x<<3)+(x<<1)+*s-'0';
        if(f) x=-x;
        if(*s) return 1;else return 0;
    }
    void deal(string &str){
        int len=str.length();
        int zm=getc(str,len);if(~zm) if(!cf) wz=zm,cf=1;
        int now=0;
        for(int nx=-1;;){
            if(str.find(zm,now)==string::npos) break;
            nx=str.find(zm,now);
            del(str,now,nx);
        }
        len=str.length();
        if(len<1) return ;
        char *snum=(char *)malloc((len+1)*sizeof(char));
        for(int i=0;i<len;i++) snum[i]=str[i];snum[len]=0;
        bool flag=1;
        for(int x;flag;) flag=read(snum,x),a[2]+=x;
    //    delete snum;
    }
    int main(){
        getline(cin,s);stringstream sio(s);
        getline(sio,A,'=');getline(sio,B);
        deal(A);
        a[1]=-a[1];a[2]=-a[2];
        deal(B);
        printf("%c=%.3lf
    ",wz,-(double(a[2])/double(a[1])));
        return 0;
    }
    /*
    hack data:
    input
    2+0x-1x=0x-x-2x
    output
    x=-1.000
    */
     1 def solve(eq,var='x'):
     2     eq1 = eq.replace("=","-(")  +  ")"
     3     eq1 = eq1.replace("x","*x")
     4     eq1 = eq1.replace("+*x","+x")
     5     eq1 = eq1.replace("-*x","-x")
     6     eq1 = eq1.replace("(*x","(x")
     7     if eq1[0] == '*':
     8         eq1 = eq1[1:]
     9     c = eval(eq1,{var:1j})
    10     #将x = 1j代入算式,结果是-9708+3j
    11     if c.real!=0:
    12         return -c.real/c.imag
    13     else:
    14         return 0
    15 test = input()
    16 ch = 'x'
    17 for i in range(len(test)):
    18     if ord('a') <= ord(test[i]) <= ord('z'):
    19         ch = test[i]
    20         test = test.replace(test[i],'x')
    21         break
    22 print("%s=%.3lf"%(ch,solve(test)))

    附 全套题解

    A:战疫情 5'

    直接枚举x,枚举y,判断x+y是否满足在区间[20000, 21000]范围内,且2*x + 100y是否刚好等于50000,如果是,则统计答案即可。

    这道题目是 题库P1047百钱买鸡 的弱化版~

    当然,手算也是很香的~

    x + y = 20000, 2x + 100y = 50000 可以求出一个x,y

    x + y = 21000, 2x + 100y = 50000 也可以求出一个x,y

    很明显,方案中y的个数是连续的。

    答案: 21

    B:行动 5'

    这个题目手算很简单!总共2020步,每4步一圈,每一圈横坐标-2,纵坐标+2。刚好505圈.

    当然这个题目也可以用循环,循环2020次。

    在第i次循环,

    如果i\%4=1,则x+i,

    如果i\%4=2,则y-i,

    如果i\%4=3,则x-i,

    如果i\%4=4,则y+i,

    答案:-1010 1010

    C:莱布尼茨公式 10'

    直接一个for循环枚举累加即可。

    注意了,C/C++选手,请使用 double!请使用 double!请使用 double!

    这次很多同学就是使用float导致精度误差,答案错误!double能够精确到15位小数左右

    答案:3.141098

    D:价值之和 10'

    质数:指在 大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。

    质因子:能整除给定正整数的 质数

    写一个函数function1

    判断一个数的每一位是否包含数字5,

    x \% 10 == 5 判断, 然后再去掉最后一位

    再写一个函数function2:

    对于一个给定的数x,判断起质因子的个数。

    直接枚举2x-1,判断是否是质数,是否是x的因子,如果是,则计数+1

    这是P1020,P1044 两题的结合

    答案:3257

    E:数方 15'

    很有意思的一道题。比较简单。

    这个题目可以手算结合编程求答案。从三位数的四次方数作为出发点,逐个确定。当然,在判断质数,三角数的时候计算量比较大,可以借助计算机,编程快速计算。

    当然这个题目,编程写,有趣的很。

    9for循环嵌套,枚举每一个数字,9个数字填好之后,再判断是否满足6个条件,如果满足,则就是答案。

    当然,如果不加优化,需要等电脑跑一会就是了~

    答案:7 2 9 4 5 7 1 6 9

    F:你好,2020 15'

    第一道编程大题~

    根据数据范围,所以数字要么是2位数,要么是4位数,要么是6位数.

    如果i6位数.则判断i\%1000是否等于[frac{i}{1000}],等于则满足条件。

    2位数,4位数的同理

    G:最优值 18'

    这是一道贪心题

    Value的计算和单词长度,首字符,以及单词再排列中的位置有关。

    单词长度固定的,首字符也是固定的,可以先计算出来。再根据|ch| * len 的值,越大的则在排列中的位置越靠后,让ID尽可能大。

    Java,C/C++选手注意了,这个题目,int型变量是肯定存不下的~

    H:计算器 22'

    这是一道模拟题~

    对于读入的字符串分割。从左到右,按照符号分割。

    统计出一个常数的和x,再统计出一个未知数的系数和y。最后x / y即可。

    I:对称迷宫 25'

    这个题目,最暴力的做法就是直接dfs,会搜索的同学,40\%的分应该要拿到。

    就是从左上角(1,1)出发,dfs,找出所有到(n, n)的路径,保存并去重,统计对称路径,计算出来的就是答案。但是只能过40\%的数据~

    时间复杂度为卡特兰数,感兴趣的可以研究一下。

    对于n<=18,做两遍dfs.

    第一遍dfs(1,1)开始搜索到中点(x+y=1)出,并将路径保存到路径1方案中。

    然后再从(n,n)跑到中点,保存路径2

    最后枚举路径1中的路径是否在路径2中出现,且中点一样。

    J:因数个数 25'

    这个题目,对于40\%的数据,还是比较好拿的。

    对于60\%的数据,需要对质数筛法有一定的了解。

    对于100\%则是考察的线性筛+桶排序,以及对数据的敏感度。

    1、对于20\%的数据。

    枚举2n中的每一个数,然后逐一求出每一个数的因数个数。对因数个数排序,找出第k小的数字即可。

    时间复杂度O(n^2)

    2、对于40\%的数据,优化一下即可。

    在逐一求每一个数的因数时枚举到sqrt{n}即可。

    时间复杂度O(nsqrt{n})

    3、对于60\%的数据

    使用质数筛法的原理,枚举2n,对于每一个数i,将其倍数都标记+1,表示有i这么一个因数。

    然后对每一个数的因数个数进行排序,求出第k小即可。

    时间复杂度O(nlogn)

    4、对于100\%的数据

    考虑线性筛算出 2N 的因数个数。d[n] 表示 n 的约数个数。

    n=p_1^{a1}*p_2^{a2}…p_k^{ak} , d[n]=(a_1+1)(a_2+1)...(a_k+1)。

    p[i]表示第 i 个质数,Min[i]表示 i 的最小质因子出现次数 + 1

    1. 当前数i是质数,d[i]=2,Min[i]=1

    2. 线筛过程中,若 i\%p[j]!=0, 则 i 不存在约数 p[j],d[p[j] * i] = 2 * d[i], Min[p[j]*i] = 1

    3. 否则,p[j]i 的最小质因子, Min[p[j] * i] = Min[i] + 1。d[p[j] * i] = frac{d[i] * Min[p[j] * i]}{(Min[i] + 1)}

    最后对d数组桶排序找出第 k 小,时间复杂度 O(N)

    对于N >= 2 * 10^7,质数的个数已经大于k了,所以直接特判就好了~

  • 相关阅读:
    POJ 2653 Pick-up sticks [线段相交 迷之暴力]
    POJ1556 The Doors [线段相交 DP]
    POJ 3304 Segments[直线与线段相交]
    POJ2318 TOYS[叉积 二分]
    挖坑
    HDU3488 Tour [有向环覆盖 费用流]
    BZOJ 3438: 小M的作物 [最小割]
    POJ 2125 Destroying The Graph [最小割 打印方案]
    网络流算法与建模总结
    CF266D. BerDonalds [图的绝对中心]
  • 原文地址:https://www.cnblogs.com/shenben/p/12294291.html
Copyright © 2020-2023  润新知