NOIP普及组初赛历年试题及答案(阅读题篇)

阅读程序写结果(共4 题,每题8 分,共计32 分)

阅读程序题是得分的关键,因为不是让你上机去运行程序,所以要一步步地读程序,记录相关变量值的变化情况。因为程序的运行结果只有输出语句才有输出,所以只写出输出语句的结果。有时要找出规律才能写出结果,特别是循环次数多的情况,另外要注意边界值,不能多算一步也不能少算一步。

解决这类问题的关键在于能够分析程序的结构以及程序段的功能。常见的有列表法、画流程图法等。完成这类题目的方法和步骤如下:

1、从头到尾通读程序,大致把握程序的算法、找出这个题目的即这个程序想干什么。抓住了它,不仅得出答案变得较容易,而且对自己的结果也会比较有信心。

2、通过给程序分段、理清程序的结构和层次,达到读懂程序的目的。

3、阅读程序中特别注意跟踪主要变量的值的变化,可以用列表的方法,了解变量变化和程序的运行结果,注意发现规律。所谓列表法,就是将各变量名作为表头,在程序的执行过程中,将各变量值的变化记录在相应变量的下方。

4、按照程序中输出格式的要求,写出运行结果,并带着结果回到程序进行检查。

在阅读程序时,要特别注意过程、函数所完成的子任务以及和主程序之间的参数传递关系。在阅读程序中,比较好的方法是首先阅读主程序,看其需要调用的过程或函数是什么,最后要求输出变量是什么;其次在阅读程序中,将较长的程序分成几个程序段(特别注意循环结构、判断结构),阅读理解各程序段的功能以及各程序之间的关联。


NOIP2011-1.
#include<iostream>
using namespace std;
int main()
{
int i,n,m,ans;
cin>>n>>m;
i=n;
ans=0;
while(i<=m){
//从i=10~20,共循环计数11次
ans+=i;
//每次循环,ans累加一次 i 值
i++;
}
cout<<ans<<endl;
//此时ans值应为(10+20)*11/2,即165
return 0;
}
输入: 10  20
输出:  165


NOIP2011-2.
#include<iostream>
#include<string>
using namespace std;
int main()
{
string map= "2223334445556667778889999";
//数组中元素位置是从0开始计数的
string tel;
int i;
cin>>tel;
for(i=0;i<tel.length();i++)
if((tel[i]>='0') && (tel[i]<='9') )
//如果输入的tel是0~9,直接输出tel值
cout<<tel[i];
else if( (tel[i]>='A') && (tel[i]<='Z'))
cout<<map[tel[i]-'A'];
//如果输入的tel是A~Z,则输出一个map数组中对应的元素
//输出元素在map数组中位置为“输入字母与A的ASCII码的差值”
//如果输入的是其他字符,比如“-”,则不符合循环条件,无输出
cout<<endl;
return 0;
}
输入: CCF-NOIP-2011
输出:  22366472011


NOIP2011-3.
#include<iostream>
#include<cstring>
using namespace std;
const int SIZE= 100;
int main()
{
int n,i,sum,x,a[SIZE];
cin>>n;
memset(a,0,sizeof(a));
for(i=1;i<=n;i++){
cin>>x;
a[x]++;
}
//循环结束时数组中的值为:a[1]=1,a[2]=2,a[3]=3,a[4]=2,a[5]=1,a[6]=2
i=0;
sum=0;
while(sum<(n/2+1)){
//当sum值大于等于n/2+1,即sum>=6的时候,循环结束
i++;
sum+=a[i];
}
cout<<i<<endl;
//输出循环结束时 i 的值(不是sum的值)
return 0;
}
输入:
11
4 5 6 6 4 3 32 3 2 1
输出: 3


NOIP2011-4.
#include<iostream>
using namespace std;
int solve(int n,int m)
{
int i,sum;
if(m==1) return 1;
//递归函数solve(i,m)中m=1时返回函数值为1
sum=0;
for(i=1;i<n;i++)
//递归函数solve(i,m)中i=1时不循环,sum=0
sum+= solve(i,m-1);
return sum;
//可递归求得sum=solve(1,3)+(2,3)+(3,3)+(4,3)+(5,3)+(6,3)
}
int main()
{
int n,m;
cin>>n>>m;
cout<<solve(n,m)<<endl;
//输出函数值,即sum值
return 0;
}
输入: 7  4
输出:  20


NOIP2012-1.
#include<iostream>
using namespace std;
int a, b, c, d, e, ans;
int main()
{
cin>>a>>b>>c;
d = a+b;
e = b+c;
ans = d+e;
//ans=a+b+b+c
cout<<ans<<endl;
return 0;
}
输入: 1 2 5
输出:  10


NOIP2012-2.
#include<iostream>
using namespace std;
int n, i, ans;
int main()
{
cin>>n;
ans = 0;
for (i = 1; i <= n; i++)
if (n % i == 0)
ans++;
//统计1~18中18的因数个数
cout<<ans<<endl;
return 0;
}
输入: 18
输出:  6


NOIP2012-3.
#include<iostream>
using namespace std;
int n, i, j,a[100][100];
int solve(int x,int y)
{
int u, v;
if(x == n)
return a[x][y];
//递归边界:当x=5时,solve(5,y)=a[5][y]
u= solve(x + 1, y);
v= solve(x + 1, y + 1);
if(u > v)
return a[x][y] + u;
else
return a[x][y] + v;
//用递归最终求得solve(1,1)=a[1][1]+solve(2,2)=2+12=14
}
int main()
{
cin>>n;
for(i = 1; i <= n; i++)
for (j = 1; j <= i; j++)
cin>>a[i][j];
cout<<solve(1,1)<<endl;
return 0;
}
输入:
5
2
-1 4
2 -1 -2
-1 6 4 0
3 2 -1 5 8
输出:  14


NOIP2012-4.
#include<iostream>
#include<string>
using namespace std;
int n, ans, i, j;
string s;
char get(int i)
{
if(i < n)
return s[i];
else
return s[i-n];
//i<8时,get(i)返回s[i];i>=8时,get(i)返回s[i-8],从第一个开始返回
}
int main()
{
cin>>s;
n= s.size();
ans= 0;
for(i = 1; i <= n-1; i++)
{
for (j = 0; j <= n-1; j++)
if (get(i+j) < get(ans+j))
{
ans = i;
break;
}
else if (get(i+j) > get(ans+j))
break;
}
//此循环执行完毕,ans=7
for(j = 0; j <= n-1; j++)
cout<<get(ans+j);
//1,ans+j<8,输出s[7+0];2,ans+j=8,输出s[8-8];3,ans+j=9,输出s[9-8]……
cout<<endl;
return 0;
}
输入:  CBBADADA
输出:  ACBBADAD


NOIP2013-1.
#include<iostream>
using namespace std;
int main()
{
inta, b;
cin>>a>>b;
cout<<a<<"+"<<b<<"="<<a+b<<endl;
return 0;
}
//输出:3+5=8
输入: 3  5
输出: 3+5=8


NOIP2013-2.
#include<iostream>
using namespace std;
int main()
{
int a, b, u, i, num;
cin>>a>>b>>u;
num = 0;
for (i = a; i <= b; i++)
if ((i % u) == 0)
num++;
//1-100之间有多少数是15的倍数
cout<<num<<endl;
return 0;
}
输入: 1  100  15
输出: 6


NOIP2013-3.
#include<iostream>
using namespace std;
int main()
{
const int SIZE = 100;
int n, f, i, left, right, middle, a[SIZE];
cin>>n>>f;
for (i = 1; i <= n; i++)
cin>>a[i];
left = 1;
right = n;
do {
middle= (left + right) / 2;
if(f <= a[middle])
right = middle;
else
left = middle + 1;
}while (left < right);
// middle=6,17>a[6],则left=7
// middle=9,17<a[9],则right=9
// middle=8,17<a[8],则right=8
// middle=7,17=a[7],则right=7
// left=right,直接输出left
cout<<left<<endl;
return 0;
}
输入:
12 17
2 4 6 9 11 15 1718 19 20 21 25
输出:  7


NOIP2013-4.
#include<iostream>
using namespace std;
int main()
{
constint SIZE = 100;
intheight[SIZE], num[SIZE], n, ans;
cin>>n;
for(int i = 0; i < n; i++) {
cin>>height[i];
num[i] = 1;
for (int j = 0; j < i; j++) {
if ((height[j] < height[i]) && (num[j] >= num[i]))
num[i] = num[j]+1;
}
}
//两两相比,得出num[0], num[1], num[2], num[3], num[4], num[5]
ans= 0;
for(int i = 0; i < n; i++) {
if (num[i] > ans) ans = num[i];
}
//得出num中最大值,即在数组height中第几位数值最大
cout<<ans<<endl;
return 0;
}
输入:
6
2  5  3  11  12  4
输出:  4


不懂算法?跟踪变量!列表模拟!遇到递归?画树形图!注意边界!找到规律了?还会流程图?恭喜你,32分到手了!


NOIP2014-1.
#include <iostream>
using namespace std;
int main()
{
int a, b, c, d, ans;
cin>> a >> b >> c;
d = a - b; //将a-b=-1赋值给d
a = d + c; //将d+c=3赋值给a
ans = a * b; //ans=a*b=3*3=9
cout<< "Ans = " << ans << endl;
return 0;
}
输入:2  3  4
输出: Ans=9


NOIP2014-2.
#include <iostream>
using namespace std;
int fun(int n)
{
if (n == 1)
return 1; //边界fun(1)=1
if (n == 2)
return 2; //边界fun(2)=2
return fun(n - 2) - fun(n - 1);
}   //fun(n)=fun(n-2)-fun(n-1)
int main()
{
int n;
cin >> n;
cout << fun(n) << endl;
//fun(7)=fun(5)-fun(6)=-11
return 0;
}
输入: 7
输出:  -11


NOIP2014-3.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string st;
int i, len;
getline(cin, st);
len = st.size();
for(i = 0; i < len; i++){
if (st[i] >= 'a' && st[i] <= 'z')
st[i] = st[i] - 'a' + 'A';
} //如果字符串st中字母小写,则替换成大写
cout<< st << endl;
return 0;
}
输入: Hello, my name is Lostmonkey.
输出: HELLO, MY NAME IS LOSTMONKEY.


NOIP2014-4.
#include <iostream>
using namespace std;
const int SIZE =100;
int main()
{
int p[SIZE];
int n, tot, i, cn;
tot= 0;
cin>> n;
for(i = 1; i <= n; i++)
p[i] = 1; //p[1]-p[30]中所有元素赋值1
for(i = 2; i <= n; i++){
if (p[i] == 1)
tot++; //计数
cn = i * 2; //找出2-30中所有2i
while (cn <= n) {
p[cn] = 0;
cn += i; //找出2-30中所有3i
}
}//对2-30中素数计数,并输出个数
cout<< tot << endl;
return 0;
}
输入: 30
输出: 10


NOIP2015-1.
#include <iostream>
using namespace std;
int main()
{
int a, b, c;
a = 1;
b = 2;
c = 3;
if(a > b) //不符合循环条件,不执行
if(a > c)
cout << a << ' ';
else
cout << b << ' ';
cout << c << endl;
return 0;
}
输出: 3


NOIP2015-2.
#include <iostream>
using namespace std;
struct point
{
int x;
int y;
}; //声明结构体类型point
int main()
{
int a, b, c;
struct EX
{
int a;
int b;
point c;
}e; //声明结构体类型EX
e.a = 1; //结构体变量e中变量a
e.b = 2; //结构体变量e中变量b
e.c.x = e.a + e.b;
//结构体变量e中的结构体变量c中的变量x
e.c.y = e.a * e.b;
//结构体变量e中的结构体变量c中的变量y
cout << e.c.x << ','<< e.c.y << endl;
return 0;
}
输出: 3,2


NOIP2015-3.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
int i;
int count;
count = 0;
getline(cin, str);
for(i = 0; i < str.length();i++)
if(str[i] >= 'a' &&str[i] <= 'z')
count++; //统计字符串中小写字母数量
cout << "It has "<< count << " lowercases" << endl;
return 0;
}
输入: NOI2016will be held in Mian Yang.
输出: It has 18 lowercases


NOIP2015-4.
#include <iostream>
#include <string>
using namespace std;
void fun(char *a, char *b)
{
a = b;
(*a)++;
} //指针题
int main()
{
char c1, c2, *p1, *p2;
c1 = 'A';
c2 = 'a';
p1 = &c1;
p2 = &c2;
fun(p1, p2);
//p1=p2=&c2,把c2的地址赋值给指针变量p1
//p1++,则有&’a’+1=&’b’, 所以,c2=’b’,
cout << c1 << c2<< endl;
return 0;
}
输出: Ab


NOIP2016-1.
#include <iostream>
using namespace std;
int main()
{
int max, min, sum, count = 0;
int tmp;
cin>> tmp;
if(tmp == 0)
return0; //如果输入的数字是0,程序退出
max= min = sum = tmp;
count++;
while(tmp != 0) {
cin>> tmp;
if(tmp != 0) {
sum += tmp; //求和
count++;//计数
if(tmp > max)
max = tmp; //找出最大值
if(tmp < min)
min = tmp; //找出最小值
}
}
cout<< max << "," << min << ","<< sum / count << endl;
//输出“最大值, 最小值, 平均值”
return 0;
}
输入: 1 2 3 4 5 6 0 7
输出:  6,1,3


NOIP2016-2.
#include <iostream>
using namespace std;
int main()
{
int i = 100, x = 0, y = 0;
while (i > 0) {
i--;
x = i % 8;
if (x == 1)
y++;
} //统计1-100中有多少数是“8的倍数+1”
cout << y << endl;
return 0;
}
输出: 13


NOIP2016-3.
#include <iostream>
using namespace std;
int main()
{
int a[6] = {1, 2, 3, 4, 5, 6};
int pi = 0;
int pj = 5;
int t , i;
while(pi < pj) {
t =a[pi];
a[pi]= a[pj];
a[pj]= t;
pi++;
pj--;
} //把数组a[6]中的数字顺序颠倒过来
for(i = 0; i < 6; i++)
cout<< a[i] << ",";
cout<< endl;
return 0;
}
输出: 6,5,4,3,2,1,


NOIP2016-4.
#include <iostream>
using namespace std;
int main()
{
int i, length1, length2;
strings1, s2;
s1= "I have a dream.";
s2 = "I Have A Dream.";
length1 = s1.size();
length2 = s2.size();
for (i = 0; i < length1; i++)
if (s1[i] >= 'a' && s1[i]<= 'z')
s1[i] -= 'a' - 'A';
//把s1里的小写字母全部换成大写
for (i = 0; i < length2; i++)
if (s2[i] >= 'a' && s2[i]<= 'z')
s2[i] -= 'a' - 'A';
//把s2里的小写字母全部换成大写
if (s1 == s2)
cout << "=" <<endl;
else if (s1 > s2)
cout << ">" <<endl;
else
cout << "<" <<endl;
return 0;
}
输出: =

*文章为作者独立观点,不代表少儿编程网立场
发表评论

坐等沙发
相关文章
新手想参加信息学竞赛NOIP ,如何入门进阶?
新手想参加信息学竞赛NOIP ,如何入门进…
从NOIP三年榜单看全国信息学竞赛形势(2017终结版)
从NOIP三年榜单看全国信息学竞赛形势(2…
IOI金牌再传秘笈:水平不高怎么拿NOIP一等奖?
IOI金牌再传秘笈:水平不高怎么拿NOIP一…
杜博闻:信息学奥赛一等奖,获三所名校保送资格!
杜博闻:信息学奥赛一等奖,获三所名校…
这些参加信息学竞赛的娃高一就保送清华!
这些参加信息学竞赛的娃高一就保送清华!
【NOIP专栏】搜狗CEO王小川的传奇人生!
【NOIP专栏】搜狗CEO王小川的传奇人生!
蒟蒻 作者
我还没有学会写个人说明!