1.数列1
问题描述
思维的严密性是相当重要的,尤其是在程序设计中,一个小小的错误,就可能导致无法想象的后果。明明的爸爸是一名富有经验的程序设计专家,深知思维严密的重要性。于是在明明很小的时候,就通过游戏的方式训练明明的思维严密性。今天,明明的爸爸和明明做了一个数列的游戏。
这个游戏很简单,就是有一数列,现在需要在数列中选出一个或者连续若干个数,要求这些数的和能被11整除。明明的爸爸想锻炼明明思维的严密性,因此要求明明尽可能多的找出符合条件的数列来,最好一个也不要漏掉。 例如有一数列为“11 22 33”,其中11可以被11整除,22可以被11整除,33可以被11整除,11+22=33能被11整除,22+33=55能被11整除,11+22+33=66能被11整除。所以以上一数列能被11整除的情况一共有六种。(注:虽然11+33也能被11整除,但是11和33在数列中没有连续出现,因此不算一种合理的情况。) 明明对这个游戏很感兴趣,高兴地玩了起来。由于粗心,明明总是无法一次就把所有的情况都找出来,这使得他爸爸不是很满意。于是明明爸爸决定先降低游戏的难度,事先告诉明明某一数列总共有多少种符合条件的选择数的方法,然后再让明明去选。明明的爸爸请你帮一个忙,他不想自己找出所有的情况,因此请你写一个程序,用程序来找出一共有多少种符合选数的情况,并把结果告诉他。 明明爸爸的问题可以归结为:给你一个数列,从中选出1个或连续若干个数,要求这些数的和能被11整除,问这样的选数方法一共有多少种。
输入说明
你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据有两行,每组测试数据的第一行有一个整数n(0<n≤50),表示数字串中有多少个整数,每组测试数据的第二行有n个整数,整数大于等于0且小于等于100,整数之间用一个空格隔开。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。
输出说明
对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将每组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个整数,即表示一共有多少种选数方法。每组运算结果单独形成一行数据,其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间没有任何空行,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。 注:通常,显示屏为标准输出设备。
个人总结
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n;
while(cin>>n){
vector<int> num(n);
vector<int> pre(n+1);
int count=0;
for(int i=0;i<n;i++){
cin>>num[i];
pre[i+1]=pre[i]+num[i];
}
for(int m=1;m<=n;m++){ //m表示连续m个数
for(int i=0;i<=n-m;i++){
int sum=pre[i+m]-pre[i];
if(sum%11==0) count++;
}
}
cout<<count<<endl;
}
return 0;
}
2.环
问题描述
明明喜欢玩游戏,而明明的爸爸也乐意陪明明玩各种各样的小游戏。但是在游戏中,明明的爸爸又十分注意培养明明的智力,他希望通过游戏,不仅能让明明得到快乐,而且又能让明明学到一些知识,锻炼他的思维能力,为将来的发展打下基础。
一天,明明的爸爸和明明做起了一个叫“环”的游戏。游戏的内容很简单但却很有趣,就是有1到9九个整数,他们以任意的顺序排列成一个圆环,然后要在这个圆环中剪一刀,再分别按顺时针和逆时针次序排列成两个九位数。现在的要求是,得到的这两个九位数差的绝对值能被396整除,问一共有几种剪环的方法。 例如九个数的排列为:1、2、3、4、5、6、7、8、9,在1和9之间剪一刀(注意:因为是一个环,所以1和9是相邻的。),顺时针形成的数为:123456789,逆时针形成的数为:987654321,这两个数的差的绝对值为:864197532,这个数能被396整除,因此这是一种符合规则的剪法,更奇妙的是,这也是这种排序方式的唯一剪法。
明明显然对这个游戏非常感兴趣,高兴地做起来。但是玩了几次后,明明发现这个游戏又并不是那么容易了,因为对于这九个数来说,虽然一共只有九种剪法,但是每种方法都要试,且还要做加法再做除法,他觉得非常的麻烦,玩着玩着就失去了兴趣。明明的爸爸发现了这个问题,于是就找到了你,他请你来帮明明一把,写一个程序,计算出某个排序中符合条件的剪法共有几种,这样的话可以大大鼓励明明玩游戏的兴致。
明明爸爸的问题可以归结为:将1至9这九个数字,以任意顺序排成一个环,请在某两个数字之间剪开,分别按顺时针和逆时针次序排列成两个九位数,要求剪开后所得到的这两个九位数的差能被396整除,问共有几种剪法?
输入说明
你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,输入的第一行有一个整数n,表示一共有多少组测试数据,接下来有n行,为n个测试数据,每组测试数据有9个数字,表示一种环的排列顺序,每个数字之间用一个空格隔开。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。
输出说明
对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个整数,即有多少种符合条件的剪法。每组运算结果的行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间没有任何空行,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。 注:通常,显示屏为标准输出设备。
个人总结
1.错误点:vector<int> extend(18); // 不仅声明了容量,还直接初始化了 18 个 0
后面的 insert 会把输入的 9 个数追加到这 18 个 0 之后,导致 extend 变成了长度为 27 的数组,且前面全是 0。
修改:用两次insert放入即可
2. 计算number:每次往右读取一位,把之前的数乘以 10 再加上新数字即可。
for(int j=i;j<i+9;j++){
number=number*10+extend[j];
}
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
//数字倒序
long long reverse(long long n){
long long reversed=0;
while(n>0){
reversed=reversed*10+n%10;
n/=10;
}
return reversed;
}
int main(){
int n;
cin>>n;
while(n>0){ //n组数据
vector<int> num(9);
vector<int> extend;
int result=0;
for(int i=0;i<9;i++){
cin>>num[i];
}
extend.insert(extend.end(),num.begin(),num.end());
extend.insert(extend.end(),num.begin(),num.end()); //放两次,解决环的问题:123456789123456789
for(int i=0;i<9;i++){ //遍历每一种分割方式 i=0表示1、9之间分割 以此类推
long long number=0; //表示顺时针的九位数
long long reversed_num; //表示逆时针的九位数
int multiple=8;
//计算number
for(int j=i;j<i+9;j++){
number=number*10+extend[j];
}
reversed_num=reverse(number);
if((abs(number-reversed_num))%396==0) result++;
}
cout<<result<<endl;
n--;
}
return 0;
}
3.修理牛棚
问题描述
在一个暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假,所以牛棚(牛棚的总数S:1<= S<=200)没有住满。 剩下的牛一个紧挨着另一个被排成一行安置在有屋顶的牛棚来过夜。 所以有些牛棚里有牛,有些没有。
所有的牛棚有相同的宽度,且宽度设为1。 因为有些门遗失,农民约翰需要架起新的木板作为门。 他的新木材供应者将会供应他任何他想要的长度,但是供应者只能提供有限数目的木板。 农民约翰想将他购买的木板总长度减到最少。
计算拦住所有有牛的牛棚所需木板的最小总长度。
输出所需木板的最小总长度作为的答案。
说明:拦住一个牛棚需要的木板长度为1,拦住相邻的三个牛棚则需要木板长度为3。
比如有牛的牛棚编号为:
3 5 8 10 11
并且只能使用两块木板,
则第一块木板从3到5,长度为3,
第二块木板从8到11,长度为4,
因此,需要木板的总长度为7。
输入说明
第 1 行: M 和 C(用空格分开)
第 2 到 C+1行: 每行包含一个整数,表示牛所占的牛棚的编号。
其中:
可能买到的木板最大的数目:M(1<= M<=50);
需要安置的牛的数目C(1<= C <=S)
安置后牛所在的牛棚的编号stall_number(1<= stall_number <= S)。
输出说明
单独的一行包含一个整数表示所需木板的最小总长度
个人总结
贪心算法类型
先用一块大长板把所有牛都盖住,然后把最长的几段‘空隙’挖掉
寻找空隙: 在这个大木板下面,盖住了很多没有牛的空牛棚(也就是空隙)。相邻两头牛之间的空隙长度为:后一头牛的编号 - 前一头牛的编号 - 1
贪心策略(挖洞): 题目允许最多使用 M 块木板。这就相当于把最初那块大长板切开 M−1 次。 为了让木板总长度最小,应该把刀下在最大的空隙处。每一次切开,就能省下那段空隙长度的木材。
#include <iostream>
#include <vector>
#include <algorithm> // 用于 sort()
using namespace std;
int main() {
int m, c; // 读取最大木板数 M 和 牛的数量 C
if (!(cin >> m >> c)) return 0;
if (m >= c) {
cout << c << endl;
return 0;
}
vector<int> stalls(c);
for (int i = 0; i < c; ++i) {
cin >> stalls[i];
}
// 从小到大排序
sort(stalls.begin(), stalls.end());
// 一整块大木板
int total_length = stalls.back() - stalls.front() + 1;
// 找出所有相邻牛棚之间的空隙
vector<int> gaps;
for (int i = 0; i < c - 1; i++) {
int gap = stalls[i+1] - stalls[i] - 1;
if (gap > 0) {
gaps.push_back(gap); // 记录大于 0 的空隙
}
}
// 将空隙从大到小排序 (rbegin 到 rend 表示逆序,即降序排列)
sort(gaps.rbegin(), gaps.rend());
// 最多切 m-1 刀,每次切在最大的空隙处,从总长度中减去这些空隙
// 切的次数不能超过实际存在的空隙数量
int cuts = min((int)gaps.size(), m - 1);
for (int i = 0; i < cuts; ++i) {
total_length -= gaps[i];
}
cout << total_length << endl;
return 0;
}
单词打卡

英语翻译
回到现代计算机的开关能力这一话题:20 世纪 70 年代的计算机通常一次只能处理 8 个开关信号。也就是说,它们在每个周期内只能处理 8 个二进制数字(比特,bit)。8 个比特组成一个字节(byte),每个字节包含 256 种由 “开 / 关”(或 “1/0”)构成的可能组合。每一种组合都对应一条指令、指令的一部分,或是某类特定数据,比如一个数字、一个字符或一个图形符号。
例如,二进制序列11010010既可能代表二进制数据 —— 在这个例子中是十进制数 210—— 也可能是一条指令,告知计算机将其开关中存储的数据与某一存储芯片位置中存储的数据进行比较。
能够一次性处理 16 位、32 位乃至 64 位数据的处理器的发展,极大提升了计算机的运算速度。计算机能够执行的全部可识别操作模式的集合,被称为指令集。这两个因素 —— 单次可处理的比特数,以及指令集的规模 —— 都随着现代数字计算机的持续发展而不断提升。

381

被折叠的 条评论
为什么被折叠?



