填空题部分
一、在计算机存储中,15.125GB是多少MB?
(15.125GB * 1024 = 15488MB)
二、1200000有多少个约数(只计算正约数)。
写个python脚本算一下得 (96)
cnt=0
for i in range(1,1200001):
if not 1200000%i:
cnt=cnt+1
print(cnt)
三、一棵包含有2019个结点的树,最多包含多少个叶结点?
昊神告诉我这叫星图,除父节点外全部是同辈的叶子节点,答案 (2018)。
四、在1至2019中,有多少个数的数位中包含数字9?
注意,有的数中的数位中包含多个9,这个数只算一次。例如,1999这个数包含数字9,在计算只是算一个数。
写个程序算一下即可,答案 (544)
for (int i=1;i<=2019;i++) {
int x=i,fl=0;
while (x) {
if (x%10==9) { fl=1; break; }
x/=10;
}
if (fl) sum++;
}
编程题(一)
问题描述
小明对类似于 (hello) 这种单词非常感兴趣,这种单词可以正好分为四段,第一段由一个或多个辅音字母组成,第二段由一个或多个元音字母组成,第三段由一个或多个辅音字母组成,第四段由一个或多个元音字母组成。
给定一个单词,请判断这个单词是否也是这种单词,如果是请输出yes,否则请输出no。
元音字母包括 (a, e, i, o, u) ,共五个,其他均为辅音字母。
输入格式
输入一行,包含一个单词,单词中只包含小写英文字母。
输出格式
输出答案,或者为 (yes) ,或者为 (no) 。
评测用例规模与约定
对于所有评测用例,单词中的字母个数不超过 (100)
——————————————————————————————
模拟题意即可,四段分开判断,遇到连续的元音/辅音就不断读入。
(f) 数组标志对应段的合法性,要注意最后还要判断一下尾部的合法性。
代码如下:
#include <bits/stdc++.h>
using namespace std;
char str[233];
int f[4],pos,len;
inline bool isy(char x) {
if (x=='a' || x=='e' || x=='i' || x=='o' || x=='u')
return true;
else return false;
}
int main() {
scanf("%s",str),len=strlen(str);
while (!isy(str[pos]) && pos<len) f[0]=true,pos++;
while (isy(str[pos]) && pos<len) f[1]=true,pos++;
while (!isy(str[pos]) && pos<len) f[2]=true,pos++;
while (isy(str[pos]) && pos<len) f[3]=true,pos++;
puts(f[0]&&f[1]&&f[2]&&f[3]&&len==pos?"yes":"no");
return 0;
}
编程题(二)
问题描述
在数列 (a[1], a[2], ..., a[n]) 中,如果对于下标 (i, j, k) 满足 (0<i<j<k<n+1) 且 (a[i]<a[j]<a[k]),则称 (a[i], a[j], a[k]) 为一组递增三元组,(a[j]) 为递增三元组的中心。
给定一个数列,请问数列中有多少个元素可能是递增三元组的中心。
输入格式
输入的第一行包含一个整数 (n)。
第二行包含 (n) 个整数 (a[1], a[2], ..., a[n]) ,相邻的整数间用空格分隔,表示给定的数列。
输出格式
输出一行包含一个整数,表示答案。
评测用例规模与约定
对于 (50%) 的评测用例,(2 <= n <= 100),(0 <= Num <= 1000) 。
对于所有评测用例,(2 <= n <= 1000),(0 <= Num <= 10000) 。
——————————————————————————————
其实就是叫我们求前面有比它小的,后面有比它大的的数的个数,想起了NOIP2014的珠心算试验...
因为 (n<=1000) ,所以可以直接用 (O(n^2)) 暴力找。
代码如下:
#include <bits/stdc++.h>
#define MAXN 10007
using namespace std;
int n,ans,a[MAXN];
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++) {
bool f1=false,f2=false;
for (int j=1;j<i;j++)
if (a[j]<a[i]) { f1=true; break; }
for (int j=i+1;j<=n;i++)
if (a[j]>a[i]) { f2=true; break; }
if (f1&&f2) ans++;
}
printf("%d",ans);
return 0;
}
当然也可以用 (ST) 表把复杂度优化为 (O(nlogn))。
代码如下:
#include <bits/stdc++.h>
#define MAXN 10007
#define INF 0x3f3f3f3f
using namespace std;
int n,ans,t1[MAXN][20],t2[MAXN][20];
inline void init() {
for (int j=1;j<=log2(n);j++)
for (int i=1;i<=n-(1<<j)+1;i++) {
t1[i][j]=min(t1[i][j-1],t1[i+(1<<(j-1))][j-1]);
t2[i][j]=max(t2[i][j-1],t2[i+(1<<(j-1))][j-1]);
}
}
inline int q1(int l,int r) {
if (l>r) return INF;
int t=log2(r-l+1);
return min(t1[l][t],t1[r-(1<<t)+1][t]);
}
inline int q2(int l,int r) {
if (l>r) return -1;
int t=log2(r-l+1);
return max(t2[l][t],t2[r-(1<<t)+1][t]);
}
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&t1[i][0]),t2[i][0]=t1[i][0];
init();
for (int i=1;i<=n;i++)
if (q1(1,i-1)<t1[i][0] && q2(i+1,n)>t1[i][0]) ans++;
printf("%d",ans);
}
最优是 (O(n)) 的,用两个数组分别从头和尾依次记录一下当前最小或最大值即可,也比较简单就不补代码了。(感谢@11eyes 提醒)。
编程题(三)
问题描述
一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数,例如 (1135) 是一个数位递增的数,而 (1024) 不是一个数位递增的数。
给定正整数 (n) ,请问在整数 (1) 至 (n) 中有多少个数位递增的数?
输入格式
输入的第一行包含一个整数 (n) 。
输出格式
输出一行包含一个整数,表示答案。
评测用例规模与约定
对于 (40\%) 的评测用例,(1 <= n <= 1000)。
对于 (80\%) 的评测用例,(1 <= n <= 100000)。
对于所有评测用例,(1 <= n <= 1000000)。
——————————————————————————————
(40) 分的做法就是在 ((1,n)) 里枚举每一个数,然后判断每位是否递增。
但是直接构造数位递增的数显然是更优的,这里用递归进行逐位构造。
边界条件:(num>n) 或 (i=9)
(我也不知道 (80) 分的范围有啥用
代码如下:
#include <bits/stdc++.h>
int n,ans=0;
using namespace std;
void dfs(int num) {
for (int i=num%10?num%10:1;i<=9;i++)
if (num*10+i<=n) ans++,dfs(num*10+i);
}
int main() {
scanf("%d",&n),dfs(0);
printf("%d",ans);
return 0;
}