3.19 2009年东莞市信息学特长生测试题 1957-1960

分数

100+0+0+80=180

T1 惊人的记忆力

希望中学的小明非常聪明,记忆力非常的好,可以达到过目不忘的程度,你任意给他一列数,他可以很快的按从小到大的顺序说出来。现在小A为了考考小明,任意给小明两列数,要求他将这两个数列中的数合并成一个数列,按从小到大的顺序说出这些数,相同的数只保留一个。现在也请你编程序来解决这个问题。

随便桶排或快排一下就好了


#include <cstdio>

using namespace std;

int a[2500],ans[2500];

int main()
{
//  freopen("a.in","r",stdin);
//  freopen("a.out","w",stdout);
    int n,t;
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&t);
        a[t+1000]++;
    }
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&t);
        a[t+1000]++;
    }
    int p=0;
    for (int i=0;i<=2000;i++)
    if (a[i]) {p++;ans[p]=i-1000;}
    for (int i=1;i<p;i++)
        printf("%d ",ans[i]);
    printf("%d",ans[p]);
}

T2 岛屿的缘分

人和人的相识是一种缘分,其实人有幸到某地也是一种缘分。某风景优美的K小岛的缘分和其他景点的缘分来得不一般,K岛上有一个石碑刻上了两个很大很大的整数x和y,和一个正整数K,后面写道:“谁能准确的写出x和y的乘积中最右边的k位数(如果乘积不足K位则在左边用“0”补足K位),他就是和K小岛有缘分的人”,李先生到了K小岛,他马上叫他的秘书算一算,写出x和y的乘积中最右边的k位数,看看李先生和他的秘书是否和K小岛有缘分。现在也请你完成这个工作(注意: 如果乘积不足K位则在左边用“0”补足K位)。

高精度乘法,然后我居然在考试时打错了。。。
事实证明考试时拍一下程序是很重要的,要是我当时随便用几个简单的乘法测一下就不会出现这么多神奇错误

#include <cstdio>
#include <string>
#include <iostream>

using namespace std;

int a[128],b[128],c[500];

int main()
{
//  freopen("b.in","r",stdin);
//  freopen("b.out","w",stdout);
    string s,t,r;
    cin>>s;
    cin>>t;
    int len1,len2;
    len1=s.size();
    for (int i=len1;i>=1;i--)
        a[len1-i+1]=s[i-1]-'0';    

    len2=t.size();
    for (int i=len2;i>=1;i--)
        b[len2-i+1]=t[i-1]-'0';

    for (int i=1;i<=len1;i++)
        for (int j=1;j<=len2;j++)
            {
                c[i+j-1]=a[i]*b[j]+c[i+j-1];
                c[i+j]+=c[i+j-1]/10;
                c[i+j-1]%=10;
            }
    int i=len1+len2;
    while (c[i]>10) 
    {
        c[i+1]=c[i]/10;
        c[i]%=10;i++;
    }
    int k;
    scanf("%d",&k);
    for (int i=k;i>=1;i--)
        printf("%d",c[i]);
}

T3 导游的魔棒

小C“五一”节参加了五星旅行社组织的一次外出旅游,这次旅游中,小C遇到一件非常有趣的事: 五星旅行社的导游小张有一根魔棒,这根魔棒在每一次的旅游中可以产生一次魔力(也只能产生一次魔力),这魔力可以使两个景点间的距离减成原来的一半。小C在“五一”节的这次旅游中,很有幸是小张导游作为他们的导游,小张当然也没有忘记带他的魔棒,因为他可以发挥魔棒的作用,使路程减少呢。这次旅游中,去了一个有N个景点的旅游区,这个旅游区只有一个入口,在景点编号为1的地方,一个出口,在景点编号为N的地方,景点编号为1,2,3,…,N。在入口处有一个N×N的数据阵,描述了景点间的距离,a[I,j]表示景点i到景点j的距离。因为小C的公司有急事要小C尽快回来,现在小C要用张导游的魔棒,使得从入口到出口的距离最短。现在我们也来编一个程序:求将哪一条边减半后使从顶点1到顶点N的最短路径长度最短,输出这个最短距离,如果找不到从1到N的路径,则输出 -1 。

有两种方法,第一种是枚举每一条边减半,然后每一次都跑最短路,取最小值;第二种是类动态规划的最短路


#include <cstdio>
#include <cstring>

using namespace std;

double d[55][55][2];

double min(double a,double b)
{
    if (a<b) return(a);
    return(b);
}

int main()
{
    int n,e=0;
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        {
            scanf("%lf",&d[i][j][0]);
            if (d[i][j][0]==0) d[i][j][0]=1006123017;
            d[i][j][1]=d[i][j][0]/2;
        }
    }
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            for (int k=1;k<=n;k++)
                if (i!=j&&j!=k&&i!=k)
                {
                    d[i][j][0]=min(d[i][j][0],
                                   d[i][k][0]+d[k][j][0]);
                    d[i][j][1]=min(d[i][j][1],
                               min(d[i][k][0]+d[k][j][1],
                                   d[i][k][1]+d[k][j][0]));
                }
    if (d[1][n][0]==1006123017) printf("-1"); else
    printf("%.2f",d[1][n][1]);
}

T4 开发区规划

小王是D市主管经济的副市长,由于经济发展的需要,要在D市组建一个高新技术开发区,经过研究,规划局在D市的东部划出了一块土地作为开发区选址。这块土地是一块矩形平原,小王准备在上面修建一些建筑。为了规划方便,他将矩形划分成N*M格。棘手的是,这块土地有些历史文化遗址散布在某些格子内,这些历史文化遗址是万万不能拆除的,否则将激起民愤,小王深知这一点,因此,他的新建筑在选址时要避开这些格子。
  假设新的建筑物有P种规格,每种建筑物都是正方形的,占地为Ti*Ti格 (1<=i<=P)。小王想知道对于每种规格的建筑,有多少种不同的合适选址方案(一种合适的选址方案指的是在该建筑所占的正方形区域内不存在有历史文化遗址的格子)。现在请你来当小王的秘书 帮他完成这个光荣而艰巨的任务。

这道题,是一道模拟。例:对于这样一个城市,我们想办法把它处理成
1011
1111
1110
1110

1011
1112
1220
1230
其中每个数字代表以该格为右下角,最多可以达成边长为多少的正方形。然后统计,每种边长都可以由比它大的边长的格子达成。

改了我2天,然后发现是数组开小了,导致数组溢出,输出了不知道什么鬼的东西。。。

#include <cstdio>

using namespace std;

int a[2018][2018],b[2018][2018],c[2018][2018],d[2018];

int min(int a,int b,int c)
{
    if (a>b) a=b;
    if (a>c) return(c);
    return(a);
}

int main()
{
    freopen("d8.in","r",stdin);
    freopen("1960.out","w",stdout);
    int n,m,p,max=0;
    scanf("%d%d%d",&n,&m,&p);
    for (int i=1;i<=n;i++)  
    {
        char s[m+1];
        scanf("%s",&s);
        for (int j=1;j<=m;j++)
          a[i][j]=s[j-1]-'0';
        for (int j=1;j<=m;j++)
          if (a[i][j]) b[i][j]=b[i][j-1]+1;
    }
    for (int j=1;j<=m;j++)
    {
        for (int i=1;i<=n;i++)
          if (a[i][j]) c[i][j]=c[i-1][j]+1;
    }
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            if (a[i][j])
            {
                a[i][j]=min(a[i-1][j-1]+1,b[i][j],c[i][j]);
                d[a[i][j]]++;
            }
    max=n;
    if (n<m) max=m;
    for (int i=max-1;i>=1;i--)
        d[i]+=d[i+1];
    for (int i=1;i<=p;i++)
    {
        int t;
        scanf("%d",&t);
        printf("%d\n",d[t]);
    }
}

猜你喜欢

转载自blog.csdn.net/yjy_aii/article/details/79629474