往年真题知多少

题目名称:珠心算测验

时间限制:1000ms内存限制:64MB

题目描述


某学校的珠心算老师采用一种快速考察珠心算加法能力的测验方法。他随机生成一个正整数集合,集合中的数各不相同,然后要求学生回答:其中有多少个数,恰好等于集合中另外两个(不同的)数之和?

输入描述

输入共两行,第一行包含一个整数n,表示测试题中给出的正整数个数。
第二行有n个正整数,每两个正整数之间用一个空格隔开,表示测试题中给出的正整数。

数据范围:
对于100%的数据,3≤n≤5000,测验题给出的正整数大小不超过10,000。

输出描述

输出共一行,包含一个整数,表示测验题答案。

样例1

输入

4 1 2 3 4

输出

2

#include<bits/stdc++.h>
using namespace std;
int n, a[105], cnt;
int vis[20005];
int main(){
    scanf("%d",&n);
    memset(vis, 0, sizeof(vis));
    for (int i = 1;i <= n;i++) scanf("%d",&a[i]);
    for (int i = 1;i < n;i++)
        for (int j = i + 1;j <= n;j++)
            vis[a[i] + a[j]] = 1;
    cnt = 0;
    for (int i = 1;i <= n;i++) cnt += vis[a[i]];
    printf("%d\n",cnt);
    return 0;
}

题目名称:传纸条

时间限制:1000ms内存限制:64MB

题目描述


小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。
在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。
还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用0表示),可以用一个0-100的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度只和最大。现在,请你帮助小渊和小轩找到这样的两条路径。

输入描述

输入的第一行有2个用空格隔开的整数m和n,表示班里有m行n列(1<=m,n<=50)。
接下来的m行是一个m*n的矩阵,矩阵中第i行j列的整数表示坐在第i行j列的学生的好心程度。每行的n个整数之间用空格隔开。

说明/提示:
30%的数据满足:1<=m,n<=10
100%的数据满足:1<=m,n<=50

输出描述

输出文件共一行一个整数,表示来回两条路上参与传递纸条的学生的好心程度之和的最大值。

样例1

输入

3 3 0 3 9 2 8 5 5 7 0

输出

34

#include<bits/stdc++.h>
using namespace std;

const int N = 55;

int n, m;
int w[N][N];
int f[2 * N][N][N];

int main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin >> w[i][j];
    for(int k = 2; k <= n + m; k++)
        for(int x1 = max(1, k -m); x1 <= min(k - 1, n); x1++)
            for(int x2 = max(1, k - m); x2 <= min(k - 1, n); x2++){
                int t = w[x1][k - x1];
                if(x1!=x2) t += w[x2][k - x2];
                for(int a = 0; a <= 1; a++)
                    for(int b = 0; b <= 1; b++){
                        f[k][x1][x2] = max(f[k][x1][x2], f[k - 1][x1-a][x2-b] + t);
                    }
            }
    cout << f[n + m][n][n] << endl;;
    return 0;
}

题目名称:字符串的展开

时间限制:1000ms内存限制:64MB

题目描述


在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类似于“d-h”或“4-8”的子串,我们就把它当作一种简写,输出时,用连续递增的字母或数字串替代其中的减号,即,将上面两个子串分别输出为“defgh”和“45678”。在本题中,我们通过增加一些参数的设置,使字符串的展开更为灵活。具体约定如下:
(1)遇到下面的情况需要做字符串的展开:在输入的字符串中,出现了减号“-”,减号两侧
同为小写字母或同为数字,且按照 ASCII 码的顺序,减号右边的字符严格大于左边的字符。
(2)参数 p1:展开方式。p1=1 时,对于字母子串,填充小写字母;p1=2 时,对于字母子串,填充大写字母。这两种情况下数字子串的填充方式相同。p1=3 时,不论是字母子串还是数字子串,都用与要填充的字母个数相同的星号“*”来填充。
(3)参数 p2:填充字符的重复个数。p2=k 表示同一个字符要连续填充 k 个。例如,当 p2=3时,子串“d-h”应扩展为“deeefffgggh”。减号两侧的字符不变。
(4)参数 p3:是否改为逆序:p3=1 表示维持原有顺序,p3=2 表示采用逆序输出,注意这时仍然不包括减号两端的字符。例如当 p1=1、p2=2、p3=2 时,子串“d-h”应扩展为“dggffeeh”。
(5)如果减号右边的字符恰好是左边字符的后继,只删除中间的减号,例如:“d-e”应输出
为“de”,“3-4”应输出为“34”。如果减号右边的字符按照 ASCII 码的顺序小于或等于左边字符,输出时,要保留中间的减号,例如:“d-d”应输出为“d-d”,“3-1”应输出为“3-1”。

输入描述

输入包括两行:
第 1 行为用空格隔开的 3 个正整数,依次表示参数 p1,p2,p3。 第 2 行为一行字符串,仅由数字、小写字母和减号“-”组成。行首和行末均无空格。

说明/提示:
40%的数据满足:字符串长度不超过 5
100%的数据满足:1<=p1<=3, 1<=p2<=8, 1<=p3<=2。字符串长度不超过 100

输出描述

输出只有一行,为展开后的字符串。

样例1

输入

1 2 1 abcs-w1234-9s-4zz

输出

abcsttuuvvw1234556677889s-4zz

样例2

输入

2 3 2 a-d-d

输出

aCCCBBBd-d

样例3

输入

3 4 2 di-jkstra2-6

输出

dijkstra2************6

#include <bits/stdc++.h>
using namespace std;
int p1,p2,p3;
string S,Ans;
char ToChar(char ch){
    if(p1==3){
        return '*';
    }
    return p1==1?tolower(ch):toupper(ch);
}
int main(){
    cin >> p1 >> p2 >> p3 >> S;
    S = ' ' + S + ' ';
    for(int i = 1;i < S.size() - 1;i++){
        if(S[i] != '-'){
            Ans += S[i];
        }else{
            char s = S[i - 1],t = S[i + 1];
            if(s < t && (islower(s) && islower(t) || isdigit(s) && isdigit(t))){
                if(p3 == 1){
                    for(char i = s + 1; i <= t - 1; i++){
                        for(int j = 0;j < p2;j++){
                            Ans += ToChar(i);
                        }
                    }
                }else{
                    for(char i = t - 1; i >= s + 1; i--){
                        for(int j = 0; j < p2; j++){
                            Ans += ToChar(i);
                        }
                    }
                }
            }else{
                Ans += '-';
            }
        } 
    }
    cout<<Ans<<endl;
    return 0;
}

题目名称:神奇的幻方

时间限制:1000ms内存限制:64MB

题目描述


幻方是一种很神奇的 N * N 矩阵:它由数字 1,2,3, … … , N * N 构成,且每行、每列及两条对角线上的数字之和都相同。
当 N 为奇数时,我们可以通过以下方法构建一个幻方: 首先将 1 写在第一行的中间。
之后,按如下方式从小到大依次填写每个数 K (K = 2,3, … , N * N) :

  1. 若 (K − 1) 在第一行但不在最后一列,则将 K 填在最后一行, (K − 1) 所在列的右一列;

  2. 若 (K − 1) 在最后一列但不在第一行,则将 K 填在第一列,(K − 1) 所在行的上一行;

  3. 若 (K − 1) 在第一行最后一列,则将 K 填在 (K − 1) 的正下方;

  4. 若 (K − 1) 既不在第一行,也不在最后一列,如果 (K − 1) 的右上方还未填数, 则将 K 填在(K − 1)的右上方,否则将 K 填在 (K − 1) 的正下方。
    现给定 N,请按上述方法构造 N * N 的幻方。

输入描述

一个整数 N,即幻方的大小。1 ≤ N ≤ 39 且 N 为奇数。

输出描述

包含 N 行,每行 N 个整数,即按上述方法构造出的 N * N 的幻方。相邻两个整数之间用单个空格隔开。

样例1

输入

3

输出

8 1 6 3 5 7 4 9 2

#include <iostream>
using namespace std;

int n, ms[40][40], x, y;

int main() {
	cin >> n;
	x = 1, y = (n + 1) / 2;
	for (int i = 1; i <= n * n; i++) {
		ms[x][y] = i;
		if (!ms[(x - 2 + n) % n + 1][y % n + 1]) 
			x = (x - 2 + n) % n + 1, y = y % n + 1;
		else x = x % n + 1;
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cout << ms[i][j] << ' ';
		}
		cout << endl;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值