编程题练习

一、N的倍数
章节: 函数
问题描述
明明的爸爸在研究一个复杂的数学问题,研究了很长时间都没有结果。明明看见后就问爸爸在研究什么。明明的爸爸回答说:“我在研究一个整数的倍数问题,想找到某个数的倍数……”明明还没有等他爸爸说完,就抢着说:“这不是很简单嘛,你把这个整数乘以1,乘以2,……,就能得到很多的倍数呀。”明明的爸爸当然知道这种方法,但是他接着说:“这样的方法找倍数当然容易,但是我找的倍数有一个特点,那个倍数只能由0或1组成,且应该尽量的小。例如一个自然数2,它符合要求的那个倍数就是10。”这下明明明白为什么爸爸研究了那么多时间都还没有研究出结果了,因为随着数字的增大,找到它的符合要求的倍数越来越难。明明想帮他爸爸解决这个问题,于是他来求助于你,能否帮他爸爸写一个程序,来求一个整数的倍数,倍数仅有0或1组成,且要尽可能小。 明明的问题可以归结为:任意给定一个自然数N,寻找一个M,要求M是N的倍数,且它的所有各位数字都是由0或1组成,并要求M尽可能小。
输入说明
你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅占一行,每行仅包括一个正整数N(1≤N≤100),代表要求倍数的那个整数。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。
输出说明
对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个整数,即N的倍数M。每组运算结果单独形成一行数据,其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间没有任何空行,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。 注:通常,显示屏为标准输出设备。
输入范例
1
2
输出范例
1
10
问题作答
完整代码
#include <bits/stdc++.h>
using namespace std;
void times(int n)
{
vector<int> parent(n, -1);
vector<int> digit(n, -1);
vector<bool> visited(n, false);
queue<int> q;
int start = 1 % n;
q.push(start);
parent[start] = -1;
digit[start] = 1;
visited[start] = true;
while (!q.empty()){
int curr = q.front();
q.pop();
if(curr == 0){
vector<int> digits;
int node = 0;
while(node != -1){
digits.push_back(digit[node]);
node = parent[node];
}
for(int i = digits.size() – 1; i >= 0; i–){
cout << digits[i];
}
cout << endl;
return;
}
int next0 = (curr * 10) % n;
if (!visited[next0]) {
visited[next0] = true;
parent[next0] = curr;
digit[next0] = 0;
q.push(next0);
}
int next1 = (curr * 10 + 1) % n;
if (!visited[next1]) {
visited[next1] = true;
parent[next1] = curr;
digit[next1] = 1;
q.push(next1);
}
}
}
int main() {
int n;
while (cin >> n)
times(n);
}
运行范例

个人总结
1.本题可以采用广度优先搜索寻找只由0和1组成且能被n整除的最小正整数,一个只包含0和1的数字,可以看作一个1不断在末尾添加0或1构建而成。
2.数字X对n的余数为r = X % n 。在X末尾添加0:新数字为10X,余数为(10r) % n ,在X末尾添加1:新数字为10X + 1,余数为(10r + 1) % n
3.vector<int> parent(n, -1); 记录状态的前驱节点,vector<int> digit(n, -1); 记录到达该状态时添加的数字(0或1),vector<bool> visited(n, false);标记状态是否访问过,queue<int> q;BFS队列
4.余数为0表示找到了能被n整除的数,需要反向追踪构建完整的数字
vector<int> digits;
int node = 0; // 从余数为0的状态开始
while (node != -1) { // 直到初始状态
digits.push_back(digit[node]); // 记录添加的数字
node = parent[node]; // 跳转到前驱状态
}
// 现在digits中存储的是从最低位到最高位的数字
// 需要反转输出
for (int i = digits.size() – 1; i >= 0; i–) {
cout << digits[i];
}
5.余数不为0,则需要设立在末尾添加0和在末尾添加1两个状态,最多搜索n个余数状态(0到n-1),每个状态扩展2个新状态,总操作次数约2n,避免本题首次编译时出现的TLE结果
二、求n天后的日期
章节: 函数
问题描述
写一个函数,传入年月日,计算它的第二天,并返回该日期。由用户输入年月日和一个n值,使用前述函数,计算该日期加n天的日期为多少。
输入说明
输入year,month,day和n共4个正整数,以空格分隔。n的值不超过2000。
输出说明
输出计算得到的结果年月日共3个正整数,整数之间以一个空格分隔,行首与行尾无多余空格。
输入范例
2000 1 1 366
输出范例
2001 1 1
问题作答
完整代码
#include <bits/stdc++.h>
using namespace std;
int day(int year, int month)
{
switch(month)
{
case 2:
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0) ? 29 : 28;
case 4:
case 6:
case 9:
case 11:
return 30;
default:
return 31;
}
}
vector<int> nextday(vector<int> date)
{
vector<int> newdate = date;
newdate[2] = date[2] + 1;
if(newdate[2] <= day(date[0], date[1]))
return newdate;
newdate[2] = 1;
newdate[1] += 1;
if(newdate[1] <= 12)
return newdate;
newdate[1] = 1;
newdate[0] += 1;
return newdate;
}
int main()
{
int year, month, day, n;
cin >> year >> month >> day >> n;
vector<int> date(3);
date[0] = year;
date[1] = month;
date[2] = day;
while(n–)
date = nextday(date);
cout << date[0] << " " << date[1] << " " << date[2];
}
运行范例

个人总结
1.本题要求写一个函数,传入年月日,计算它的第二天,并返回该日期,由用户输入年月日和一个n值,使用该函数,计算该日期加n天的日期即为调用该函数n次,得到n天后的日期
2.写一个int day(int year, int month)作为辅助函数,求一个月的最大天数,判断日期是否超距
三、菱形输出
章节: 函数
问题描述
明明这次又碰到问题了:
给定一个正整数N,明明的爸爸让他输出一个以Z开始的菱形,以后依次为Y,X…,
比如当N等于1的时候输出图形:
Z
当N等于2的时候,输出图形:(Y前没有空格,Z、X和W前一个空格)
Z
Y X
W
当N等于3的时候,输出图形(Z前两个空格,Y、X前一个空格,W前没有空格……):
Z
Y X
W V
U T
S
明明发现当N很大的时候就不是很容易了,所以找到了你,希望你编写一个程序帮助他
明明的问题可以归结为:输入一个正整数N,输出一个以Z开始的菱形,以后依次为Y,X…。
请尝试定义函数,该函数的功能是输出以上图形的一行。
输入说明
你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅占一行,每行仅包括一个正整数n(1≤n≤7)。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。
输出说明
对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组输出一个以Z开始的菱形,具体格式参照样例输出。每组运算结果与其后一组运算结果之间有一个空行,最后一组运算结果之后没有空行。 注:通常,显示屏为标准输出设备。
输入范例
1
3
输出范例
Z
Z
Y X
W V
U T
S
问题作答
完整代码
#include <bits/stdc++.h>
using namespace std;
void output(int n)
{
vector<char> zyx = {'Z','Y','X','W','V','U','T','S','R','Q','P','O','N','M','L','K','J','I','H','G','F','E','D','C','B','A'};
int cursor = 0;
for(int i = 0; i < n; i++){
if(i == 0){
cout << setw(n) << zyx[cursor] << endl;
cursor++;
}else{
cout << setw(n – i) << zyx[cursor];
cursor++;
cout << setw(2 * i) << zyx[cursor] << endl;
cursor++;
}
}
for(int i = n – 2; i >= 0; i–){
if(i == 0){
cout << setw(n) << zyx[cursor] << endl;
cursor++;
}else{
cout << setw(n – i) << zyx[cursor];
cursor++;
cout << setw(2 * i) << zyx[cursor] << endl;
cursor++;
}
}
cout << endl;
}
int main()
{
int n;
while(cin >> n)
output(n);
}
运行范例

个人总结
1.本题要求输出固定规律的格式的字母,可以先固定要输出的字母数组
2.通过输出范例可知,以上半图形为例,第一行前有n-1个空格,第二行的第一个元素前有n-2个空格,第二行的第二个元素前有1个空格,第三行的第一个元素前有n-3个空格,第三行的第二个元素前有3个空格,使用setw()固定格式,除第一行外,每行第一个元素前有n-1-i个空格,cout << setw(n – i) << zyx[cursor];,即第一个元素共占n-i格,每行第二个元素前有2i-1个空格,cout << setw(2 * i) << zyx[cursor];,即第二个元素共占2i格
翻译练习
第一段
原文

译文
GPS在1973年由美国的空军开发,类似的发展也已经在欧盟、俄罗斯和中国发生。自1994年以来,降级的全球定位系统已可用于民用应用,提供可靠的定位、导航和定时服务。对于任何拥有全球定位系统接收器的人来说,该系统将在世界各地的任何天气条件下,白天和黑夜,为无限数量的用户提供准确的位置和时间信息。
表12C-1:物联网的启用和协同技术
第二段
原文

译文
协同技术发挥支持作用。例如,生物识别技术可以广泛应用于个性化人类、机器和物体之间的交互。人工智能、计算机视觉、机器人技术和远程呈现技术可以使我们的生活在未来更加自动化。
第三段
原文

译文
作为一项新兴技术,物联网将变得更加成熟和复杂。图 12C-1 显示了可能受益于物联网的主要技术进步和关键应用。例如,供应链现在得到了比以往更好的支持。垂直市场应用可能代表着下一波进步。随着我们走向 2020 年,无处不在的定位有望成为现实。除此之外,全球规模的物理物联网可能会到位。这些进步将显著提升人类能力、社会成果、国家生产力和生活质量。
图12C-1:物联网技术路线图
单词练习

网硕互联帮助中心







评论前必须登录!
注册