llq 元旦狂欢 第三发

话说新的一年到了 quanquan先在这里给大家拜个年
llq还是很会挑时间的 在新年的五个小时之前很给力的考了个试
虽然我考的并不是很好。。。。。。。。。。
但是没关系 再接再厉么
好了 现在大家来看一看本次考试题及题解吧

我承认我是粘的题干,,,,,不要抽我

  1. 矿机购买(id)
    【题目描述】 6Bit 最近迷上了比特币挖矿,但是 CPU 挖矿和 GPU 挖矿的模式实在太 low 了,于是 6Bit 准备去买几 台矿机专门来挖矿。 但是矿机网站搞饥饿营销,每人只允许买一台矿机,网站使用身份证号来区分是否是同一个人,于是 6Bit 就需要编一些身份证号就注册新帐号来买矿机,可是没想到身份证号竟然有一位是验证位,6Bit 编出 来的身份证号有的不合法,好心的你帮忙看看,6Bit 编的身份证号是否合法,合法就直接输出合法的身份 证号,不合法的,请你帮忙把最后一位的验证位给改过来,输出一个合法的身份证号。 现知道身份证最后一位的校验位的计算方法如下: 1、将前面的身份证号码 17 位数分别乘以不同的系数。从第一位到第十七位的系数分别为: 7, 9,10, 5,8,4,2,1,6,3,7,9,10,5,8,4,2; 2、将这 17 位数字和系数相乘的结果相加; 3、用加出来和除以 11,看余数是多少; 4、余数只可能有 0,1,2,3,4,5,6,7,8,9,10 这 11 个数字。其分别对应的最后一位身份证 的号码为 1,0,X,9,8,7,6,5,4,3,2; 5、通过上面得知如果余数是 2,就会在身份证的第 18 位数字上出现罗马数字的 X。如果余数是 10, 身份证的最后一位号码就是 2。
    【输入】 输入一行身份证号。
    【输出】 输出第一行为此身份证号对应的合法身份证号。
    【输入输出样例】 id.in id.out 340524198001010012 34052419800101001X
    【数据范围】 身份证号长度均为 18 位,最后一位如果是字母,为大写 X。
    【样例解释】 样例身份证号的前 17 位为 34052419800101001
    按公式计算 3*7+4*9+0*10+5*5+2*8+4*4+1*2+9*1+8*6+0*3+0*7+1*9+0*1+1*5+0*8+0*4+1*2 结果为 189%11 = 2 余 数 0 1 2 3 4 5 6 7 8 9 10 校验位 1 0 X 9 8 7 6 5 4 3 2 根据规则可得最后一位校验位为 X。 则正确身份证号为:34052419800101001X。

这是一道送分题。。。按照llq的说法 会编程的都会。。。
我又成功的挂了两个点。。。。。。
没办法。。。。。
好了现在正式讨论做法
01. 首先正常人的思维绝对是用字符串做。。。。。不过有一点要注意。。就是如果在字符串上直接乘除 。。。。你有50%的几率爆掉一个char 没错 爆char
02. 不太正常的人的做法, 大家绝对不了解c++发明者的古怪的心思.。。你敢相信,,,它可以用。。。用。。。scanf("%1d",&a[i]) 直接进行各位分割的读入。。。。。这个发明者真是。。。真是贴心极了
03.不管怎么样 你得拿这道水题的满分。。。。。。。。。。
下面是01的代码

using namespace std;
char str[19];
int a[19];
int sum=0;
int c[19]={0,7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
int main()
{
    freopen("id.in", "r", stdin);
    freopen("id.out", "w", stdout);
    scanf("%s",str+1);
    for(int i=1;i<=17;i++)
        a[i]=str[i]-'0';
    for(int i=1;i<=17;i++)
    {
        int tmp=a[i];
        tmp*=c[i];
        sum+=tmp;
    }
    sum%=11;
    if(sum==0) 
        a[18]=1;
    else if(sum==1) 
            a[18]=0;
         else 
            a[18]=12-sum;
    for(int i=1;i<=17;i++)
        printf("%d",a[i]);
    if(a[18]==10)
        cout<<"X";
    else
        printf("%d",a[18]);
    fclose(stdin);
    fclose(stdout);
}

额 02的代码你们自己改吧 改一丢丢#include 就可以

下面是标称 你们需要 一点 时间理解

int main()
{
    freopen("id.in","r",stdin);
    freopen("id.out","w",stdout);
    const int mo = 11;
    int i, L = 17, ans = 0, e = 1;
    char str[20];
    gets(str);
    for(i=1; (12 - ans) % mo;
    str[L] = ans==10 ? 'X' : ans+'0';
    puts(str);
}

莱特币(ltc)
【题目描述】 6Bit仔细检查了一下矿机,发现挖矿机虽然挖比特币有 bug,但挖莱特币还是很好使的,虽然莱特币 没有比特币值钱。换算成莱特币,矿机的成本是 Y 莱特币。 现在 6Bit推算出了,从今天往后 N 天,每天可以挖出的莱特币数,请你帮忙计算一下,6Bit最快连续 挖矿多少天可以回本,如果回不了本则输出 0.
【输入】 第一行两个整数 Y、N(表示矿机的成本为 Y,推算出 N 天的莱特币出矿数)。 第二行有 N 个整数,Ai表示第 i 天可以挖出的莱特币数。
【输出】 输出一个整数,表示如果 6Bit要回本,至少要使用矿机连续挖矿多少天。
【输入输出样例】 ltc.in ltc.out 15 10 5 1 3 5 10 7 4 9 2 8 2
【数据范围】 对于 30%的数据,N <= 500。 对于 70%的数据,N <= 104。 对于 100%的数据,1 <= Y <= 108,1 <= N <6Bit要回本,至少要使用矿机连续挖矿多少天。
【输入输出样例】 ltc.in ltc.out 15 10 5 1 3 5 10 7 4 9 2 8 2
【数据范围】 对于 30%的数据,N <= 500。 对于 70%的数据,。
1 <= i <= S。
【样例解释】 6Bit在第 4 天开始,连续采矿 2 天,收益为 5+10=15
正好回本。 在或者 6Bit也可以第 5 天开始,连续采矿 2 天,益为 10+7=17>15,回本。

这题直接体现了 一个人的智商。。。。
智商。。。。。。。
1.30分做法 暴力 立方做法。。。没什么说的 模拟就行。。。。。我才不要给这种代码
2.70分做法 前缀和数组 用前缀和的方式减少时间复杂度 代码一会给。。。
3.100 01做法 前缀和加二分 没什么说的
4.100 02做法 重点来了 尺取法 尺取法就是两个指针表示区间[l,r]的开始与结束然后根据题目来将端点移动,是一种十分有效的做法。适合连续区间的问题 本题就可以 用这种奇怪的方法

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int a[100001];
int y,n;
int main()
{
    int times;
    scanf("%d",&times);
    for(int kk=1;kk<=times;kk++)
    {
        memset(a,0,sizeof(a));
        scanf("%d%d",&n,&y);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int ans=n+1;
        long long sum=0;
        for(int i=1,j=1;j<=n;j++)
        {
            sum+=a[j];
            if(sum<=y) continue;
            while(sum>=y&&i<=j)
            {
                sum-=a[i];
                i++;
            }
            ans=min(ans,j-i+2);
        }
        if(ans>n)
            cout<<'0'<<endl;
        else
            cout<<ans<<endl;
    }
}
#include <stdio.h>
int a[100001];
int judge (int x,int y,int n);
int  mul (int x); 
int y,n;
int main()
{
    freopen("ltc.in","r",stdin);
    freopen("ltc.out","w",stdout);
    scanf("%d%d",&y,&n);
    long long ans=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        ans+=a[i];
    }
    if(ans<y)
        printf("0");
    else
        printf("%d",judge(1,n,y));
} 
int judge (int x,int y,int n)
{
    while(x<y)
    {
        int tmp=(x+y)/2;
        if(mul(tmp))
            y=tmp;
        else    
            x=tmp+1;
    }
    return x;
}
int mul (int x)
{
    for(int j=1;j<=n-x;j++)
    {   
        long long sum=0;
        for(int k=j;k<j+x;k++)
    ` sum+=a[k]; if(sum>=y) `
````````
    {
            return 1;
        }
    }
    return 0;
}

你可能感兴趣的:(算法,考试)