首页 > 代码库 > 5.13考试整理 x

5.13考试整理 x

5.13五一清北基础班试题

1、洛谷P1149 火柴棒等式时空限制1s / 128MB

题目描述

给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是0)。用火柴棍拼数字0-9的拼法如图所示:

 

注意:

1.加号与等号各自需要两根火柴棍

2.如果A≠B,则A+B=C与B+A=C视为不同的等式(A、B、C>=0)

   3.n根火柴棍必须全部用上

输入输出格式

输入格式:

输入文件matches.in共一行,又一个整数n(n<=24)。

输出格式:

输出文件matches.out共一行,表示能拼成的不同等式的数目。

输入输出样例

输入样例#1:

样例输入1:

14

样例输入2:

18

输出样例#1:

样例输出1:

2

样例输出2:

9

说明

【输入输出样例1解释】

2个等式为0+1=1和1+0=1。

【输入输出样例2解释】

9个等式为:

0+4=4     0+11=11    1+10=11

2+2=4     2+7=9      4+0=4

7+2=9     10+1=11    11+0=11

思路:

  搜索,如果找到满足条件的ans++,

其实我的本意是打表的,敲了一个看似正确的代码出来,但是是真的不敢用(怕超时)……,所以交了打表代码上去(奇迹般的过了……)

打表代码:

技术分享
#include <iostream>#include <cstdio>using namespace std;int main(){    int cc;    scanf("%d",&cc);    switch(cc)    {        case 0 :        case 1 :        case 2 :        case 3 :        case 4 :        case 5 :        case 6 :        case 7 :        case 8 :        case 9 :        case 10 :        case 11 :        case 12 :            printf("0");            break;         case 13 :            printf("1");            break;        case 14 :            printf("2");            break;        case 15 :            printf("8");            break;        case 16 :        case 17 :        case 18 :            printf("9");            break;        case 19 :            printf("29");            break;        case 20 :            printf("39");            break;        case 21 :            printf("38");            break;        case 22 :            printf("65");            break;        case 23 :            printf("88");            break;        case 24 :            printf("128");            break;    }    return 0;}//其实还有一种更为简单的打表方式哦~(打表之一)//如下:/*#include<iostream>#include<cstdio>using namespace std;int QAQ[10001]={0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,8,9,6,9,29,39,38,65,88,128};int main(){    int n;    scanf("%d",&n);    cout<<QAQ[n];    return 0;}//打表之二*/
打表

而另外一种就是正解啦!

(搜索!看着其实是挺像暴力的hh)

如下:

 

技术分享
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <string>#include <cstring>#include <cmath>#include <cstdlib>using namespace std;int QAQ[10]= {6,2,5,5,4,5,6,3,7,6};//存放每个数字所需要的火柴棒数int x,y,k,n;int qwq(int n) //进行判断是否满足条件{    int q=0;    do    {        q=q+QAQ[n%10]; //取出个位数,进行判断需要使用多少根火柴棒        n=n/10; //继续进行下去    }    while(n);    return q; //用来计数}int main(){    cin>>n;    for(x=0; x<=1000; x++)        for(y=0; y<=1000; y++)            if(qwq(x)+qwq(y)+qwq(x+y) == n-4)                k++;    cout<<k;    return 0;}
正解

2、洛谷P1113 杂务

题目描述

John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它。比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及一些其它工作。尽早将所有杂务完成是必要的,因为这样才有更多时间挤出更多的牛奶。当然,有些杂务必须在另一些杂务完成的情况下才能进行。比如:只有将奶牛赶进牛棚才能开始为它清洗乳房,还有在未给奶牛清洗乳房之前不能挤奶。我们把这些工作称为完成本项工作的准备工作。至少有一项杂务不要求有准备工作,这个可以最早着手完成的工作,标记为杂务1。John有需要完成的n个杂务的清单,并且这份清单是有一定顺序的,杂务k(k>1)的准备工作只可能在杂务1..k-1中。

写一个程序从1到n读入每个杂务的工作说明。计算出所有杂务都被完成的最短时间。当然互相没有关系的杂务可以同时工作,并且,你可以假定John的农场有足够多的工人来同时完成任意多项任务。

输入输出格式

输入格式:

1行:一个整数n,必须完成的杂务的数目(3<=n<=10,000);

2 ~ n+1行: 共有n行,每行有一些用1个空格隔开的整数,分别表示:

工作序号(1..n,在输入文件中是有序的);

完成工作所需要的时间len(1<=len<=100);

   一些必须完成的准备工作,总数不超过100个,由一个数字0结束。有些杂务没有需要准备的工作只描述一个单独的0,整个输入文件中不会出现多余的空格。

输出格式:

一个整数,表示完成所有杂务所需的最短时间。

输入输出样例

 

 

输入样例#1:

7

1 5 0

2 2 1 0

3 3 2 0

4 6 1 0

5 1 2 4 0

6 8 2 4 0

7 4 3 5 6 0

输出样例#1:

23

思路:

  一看到这道题,我就不自觉地想起了拓扑排序!额……对于如此,能够想到方法毕竟还是好的嘛!所以抓紧时间的敲了一份拓扑排序(自认为是非常正确的!),可是现实是血淋淋的……,

爆零了耶……可怕……

代码:

(出错在哪里了呢…其实这可能是我最最最长的一份代码…)

如下:

技术分享
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <string>#include <cstring>#include <cmath>#include <cstdlib>using namespace std;const int M = 10005;int n;//3 <= n <= 10,000int ans;int que[M],H[M];int deg[M];int now;int fg;struct B{    int num;    int len;    int nxt;    int vv;    int cengshu;//杂务k(k>1)的准备工作只可能在杂务1..k-1中}v[M]; void Ins(int u, int vv, int w)//邻接表 {    ++now;    v[now].vv = vv;    v[now].len = w;    v[now].nxt = H[u];    H[u] = now;}void TO(){    int h,t,i,j;    for (i = 1; i <= n; i ++)        for (j = H[i]; j != -1; j = v[j].nxt)        {            int vx = v[j].vv;            deg[vx] ++;        }    h = t = 0;     for (i=1;i<=n;i++)    {        if (deg[i]) continue;        que[t] = i; t ++;        if(v[i].len > ans) ans=v[i].len;    }    int nowans=ans,nowceng=2;    for (;h < t;h++)    {        int u = que[h];//队头元素         if(v[u].cengshu != nowceng)        {            nowceng++;            nowans=ans;        }                int aa=0;        for (i = H[u]; i != -1; i = v[i].nxt)        {            int vq = v[i].vv;            deg[vq] --;//删边            aa++;            if(aa==1)            {                if(nowans+v[vq].len > ans) ans=v[vq].len+nowans;            }            if (deg[vq] == 0)            {                que[t] = vq;                t ++;            }        }    }}int main(){    scanf("%d",&n);    int qm,numm,lenm;    for(int i=1;i<=n;i++) H[i]=-1;     int cc;    for(int i=1;i<=n;i++)    {        scanf("%d%d",&numm,&lenm);//编号(应该)是1-n顺下来的        cc=0;        while(scanf("%d",&qm) == 1)        {            if(qm == 0)            {                break;            }            Ins(numm,qm,lenm);//numm连接的下一条边是qm             cc++;        }        switch(cc)        {            case 0 : v[i].cengshu=1;break;            case 1 : v[i].cengshu=2;break;            case 2 : v[i].cengshu=3;break;            case 3 : v[i].cengshu=4;break;            case 4 : v[i].cengshu=5;break;            case 5 : v[i].cengshu=6;break;            case 6 : v[i].cengshu=7;break;            case 7 : v[i].cengshu=8;break;            case 8 : v[i].cengshu=9;break;            case 9 : v[i].cengshu=10;break;            case 10 : v[i].cengshu=11;break;            case 11 : v[i].cengshu=12;break;            case 12 : v[i].cengshu=13;break;            case 13 : v[i].cengshu=14;break;            case 14 : v[i].cengshu=15;break;            case 15 : v[i].cengshu=16;break;            case 16 : v[i].cengshu=17;break;            case 17 : v[i].cengshu=18;break;            case 18 : v[i].cengshu=19;break;            case 19 : v[i].cengshu=20;break;            case 20 : v[i].cengshu=21;break;            case 21 : v[i].cengshu=22;break;            case 22 : v[i].cengshu=23;break;            case 23 : v[i].cengshu=24;break;            case 24 : v[i].cengshu=25;break;            case 25 : v[i].cengshu=26;break;            case 26 : v[i].cengshu=27;break;            case 27 : v[i].cengshu=28;break;            case 28 : v[i].cengshu=29;break;            case 29 : v[i].cengshu=30;break;            case 30 : v[i].cengshu=31;break;            case 31 : v[i].cengshu=32;break;            case 32 : v[i].cengshu=33;break;            case 33 : v[i].cengshu=34;break;            case 34 : v[i].cengshu=35;break;            case 35 : v[i].cengshu=36;break;            case 36 : v[i].cengshu=37;break;            case 37 : v[i].cengshu=38;break;            case 38 : v[i].cengshu=39;break;            case 39 : v[i].cengshu=40;break;            case 40 : v[i].cengshu=41;break;            case 41 : v[i].cengshu=42;break;            case 42 : v[i].cengshu=43;break;            case 43 : v[i].cengshu=44;break;            case 44 : v[i].cengshu=45;break;            case 45 : v[i].cengshu=46;break;            case 46 : v[i].cengshu=47;break;            case 47 : v[i].cengshu=48;break;            case 48 : v[i].cengshu=49;break;            case 49 : v[i].cengshu=50;break;            case 50 : v[i].cengshu=51;break;            case 51 : v[i].cengshu=52;break;            case 52 : v[i].cengshu=53;break;            case 53 : v[i].cengshu=54;break;            case 54 : v[i].cengshu=55;break;            case 55 : v[i].cengshu=56;break;            case 56 : v[i].cengshu=57;break;            case 57 : v[i].cengshu=58;break;            case 58 : v[i].cengshu=59;break;            case 59 : v[i].cengshu=60;break;            case 60 : v[i].cengshu=61;break;            case 61 : v[i].cengshu=62;break;            case 62 : v[i].cengshu=63;break;            case 63 : v[i].cengshu=64;break;            case 64 : v[i].cengshu=65;break;            case 65 : v[i].cengshu=66;break;            case 66 : v[i].cengshu=67;break;            case 67 : v[i].cengshu=68;break;            case 68 : v[i].cengshu=69;break;            case 69 : v[i].cengshu=70;break;            case 70 : v[i].cengshu=71;break;            case 71 : v[i].cengshu=72;break;            case 72 : v[i].cengshu=73;break;            case 73 : v[i].cengshu=74;break;            case 74 : v[i].cengshu=75;break;            case 75 : v[i].cengshu=76;break;            case 76 : v[i].cengshu=77;break;            case 77 : v[i].cengshu=78;break;            case 78 : v[i].cengshu=79;break;            case 79 : v[i].cengshu=80;break;            case 80 : v[i].cengshu=81;break;            case 81 : v[i].cengshu=82;break;            case 82 : v[i].cengshu=83;break;            case 83 : v[i].cengshu=84;break;            case 84 : v[i].cengshu=85;break;            case 85 : v[i].cengshu=86;break;            case 86 : v[i].cengshu=87;break;            case 87 : v[i].cengshu=88;break;            case 88 : v[i].cengshu=89;break;            case 89 : v[i].cengshu=90;break;            case 90 : v[i].cengshu=91;break;            case 91 : v[i].cengshu=92;break;            case 92 : v[i].cengshu=93;break;            case 93 : v[i].cengshu=94;break;            case 94 : v[i].cengshu=95;break;            case 95 : v[i].cengshu=96;break;            case 96 : v[i].cengshu=97;break;            case 97 : v[i].cengshu=98;break;            case 98 : v[i].cengshu=99;break;            case 99 : v[i].cengshu=100;break;            case 100 : v[i].cengshu=101;break;        }    }    TO();    printf("%d",ans);    return 0;}
不要问我为什么打了100多行表……

慌张跑去问大佬!大佬给出的代码是这样的:

技术分享
#include<iostream>#include<cstdio>#include<queue>#include<algorithm>using namespace std;const int N = 10005;queue <int> q;bool e[N][N];int ti[N];int mx[N];int ru[N];int n,ans;void topo(){    for(int i=1;i<=n;++i)        if(ru[i] == 0)         {            q.push(i);            mx[i] = ti[i];        }    while(!q.empty())    {        int d = q.front();        q.pop();        for(int i=1;i<=n;++i)        {            if(e[d][i])            {                ru[i]--;                if(ru[i]==0) q.push(i);                mx[i] = max(mx[i],mx[d]+ti[i]);            }        }    }    for(int i=1;i<=n;++i)        ans = max(ans,mx[i]);}int main(){    scanf("%d",&n);    for(int i=1;i<=n;++i)    {        int a,b,c;        scanf("%d%d%d",&a,&b,&c);        ti[a] = b;        while(c!=0)        {            ru[a]++;            e[c][a] = true;             scanf("%d",&c);        }    }    topo();    printf("%d",ans);    return 0;}
Topo

正确思路:

  在进入每一层时,都求出到达这个点的最大时间.(因为我们要保证所有的任务都完成才行)

(疑似动规?)

 

3、洛谷P2782 友好城市

题目描述

有一条横贯东西的大河,河有笔直的南北两岸,岸上各有位置各不相同的N个城市。北岸的每个城市有且仅有一个友好城市在南岸,而且不同城市的友好城市不相同。没对友好城市都向政府申请在河上开辟一条直线航道连接两个城市,但是由于河上雾太大,政府决定避免任意两条航道交叉,以避免事故。编程帮助政府做出一些批准和拒绝申请的决定,使得在保证任意两条航道不相交的情况下,被批准的申请尽量多。

输入输出格式

输入格式:

1行,一个整数N(1<=N<=5000),表示城市数。

2行到第n+1行,每行两个整数,中间用一个空格隔开,分别表示南岸和北岸的一对友好城市的坐标。(0<=xi<=10000)

输出格式:

仅一行,输出一个整数,表示政府所能批准的最多申请数。

输入输出样例

输入样例#1:

7

22 4

2 6

10 3

15 12

9 8

17 17

4 2

输出样例#1:

4

说明

1<=N<=5000,0<=xi<=10000

 思路:

  因为是说建造最多多少航道才能够不重复,所以将给出的南岸坐标(连带着北岸)进行排序,如果找到最长的上升子序列,那么就是最多能够建造的航道.

巧妙的转化代码~

 

技术分享
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <string>#include <cstring>#include <cmath>#include <cstdlib>using namespace std;//思路:根据南岸的坐标排好序之后,寻找北岸的最长上升子序列const int M = 5005;int n; //5000int f[M];struct A{    int nx;//0<=xi<=10000    int bx;    bool operator < (const A &q ) const    {        return nx < q.nx;    }}zb[M];int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d%d",&zb[i].nx,&zb[i].bx);    }    sort(zb+1,zb+1+n);    f[1]=1;    for(int i=2;i<=n;i++)//第一个点的上升子序列一定为1(because 前面没有数)     {        for(int j=1;j<=i-1;j++)//通过前面已经找好了的序列更新当前序列            if(zb[i].bx > zb[j].bx && f[i] < f[j])//求上升子序列                f[i]=f[j];        f[i]++;            }    int maxx=0;    for(int i=1;i<=n;i++)    {        if(f[i]>maxx) maxx=f[i];    }    printf("%d",maxx);    return 0;}
友好城市

 

小结:

(以为会100+100+100果然是想多了……AK遥远……啧啧)

 

 真实分数(100+0+100)

对于中间的零,我无话可说……错了就是错了,我需要找出自己错在哪里的!

第二题我的想法是topo+乱搞(还想了一种挺厉害的方法!可惜无法实现……直到大佬告诉我原来开[10005][10005]的数组能够AC,感觉特失望……,我本来不想写邻接表,因为我只是背过代码,具体意思一直是没有搞明白的,所以呢,这告诉我们一定要写自己会的,认为绝对正确的!不能够盼望着瞎猫碰上死耗子什么的,但是多了一分技巧就多一分把握!所以要搞懂邻接表!)

还有就是骗分过样例之后,应该自己再造几组数据!第二题就是过了样例草草上交。。。

5.13考试整理 x