2020年省A一模
A、单位变换
在计算机存储中,15.125GB是多少MB?
思路:15.125*1024=15488
B、约数个数
1200000有多少个约数(只计算正约数)
96:从1遍历到sqrt(x),结果乘2即可
int main(){
int cnt=0,in=1200000;
for (int i=1;i<int(sqrt(in))+1;i++){
if (in%i==0){
cout<<i<<" "<<in/i<<endl;
cnt+=1;
}
}
cout<<cnt*2<<endl;
return 0;
}
C、叶节点数
一棵包含有2019个结点的二叉树,最多包含多少个叶结点?
思路:设n0、n1、n2、n分别为叶子节点个数、度为1的节点个数、度为2的节点个数、总节点数,对任意二叉树有:n=n0+n1+n2,n0=n2+1
联立可得:n=2*n0+n1-1。当n=2019时若n1取最小值0,则n0最大为1010
D、数字9
在1至2019中,有多少个数的数位中包含数字9?
544:遍历
int main(){
int cnt=0,x;
for (int i=1;i<2020;i++){
x = i;
while (x){ //找9
if (x%10==9){
cnt+=1;
cout<<i<<endl;
break;
}
else x/=10;
}
}
cout<<cnt;
return 0;
}
2020年省A二模
A、容量单位
在计算机存储中,12.5MB是多少字节?
13107200 = 12.510241024
B、最多边数
一个包含有2019个结点的有向图,最多包含多少条边?(不允许有重边)
4074342 = 2019*2018,每个点向其它点建立线段
C、单词重排
将LANQIAO中的字母重新排列,可以得到不同的单词,如LANQIAO、AAILNOQ等,注意这7个字母都要被用上,单词不一定有具体的英文意义。请问,总共能排列如多少个不同的单词。
2个A,1个I、L、N、O、Q,则A(7,5) = 76543=2520
D、括号序列
由1对括号,可以组成一种合法括号序列:()。
由2对括号,可以组成两种合法括号序列:()()、(())。
由4对括号组成的合法括号序列一共有多少种?
14:用栈判断是否合法+dfs全排列
#include <stack>
int res=0;
bool legal(string x){
stack<char> s;
for (int i=0;i<x.size();i++){
if (x[i]=='(') s.push('('); //左括号入栈
else{//右括号则将栈顶出栈
if (s.size()) s.pop();
else return false;
}
}
if (s.size()==0) return true; //匹配
else return false;
}
void dfs(int cnt,string x){
if (cnt==7){
x=x+")";//最后一个括号必为右括号
if (legal(x)==true) res+=1;
return;
}
dfs(cnt+1,x+"(");
dfs(cnt+1,x+")");
}
int main(){
dfs(0,"");
cout<<res<<endl;
return 0;
}
2020年省A第一场
A、跑步训练
3880:按条件循环
int main(){
int in=10000,res=0;
while (in){
if (in>600){//可以恢复
in-=300;
res+=120;
}
else{//每秒消耗10
res+=in/10;
break;
}
}
cout<<res;
return 0;
}
B、合并检测
10:(k+1)+(100-k)/k = k+100/k 求函数最小值时k=多少
C、分配口罩
市长获得了15批口罩,每批口罩数量如下:
9090400
8499400
5926800
8547000
4958200
4422600
5751200
4175600
6309600
5865200
6604400
4635000
10663400
8087200
4554000
现在要将口罩分配给市内两个医院,由于物流限制每一批口罩只能分配给其中一家医院,希望两家医院的口罩总数之差越小越好,请计算这个最小差是多少。
2400:贪心只能取得局部最小,用深搜来一个个看情况,求最小值
typedef long long ll;
ll in[16],mini=10000000000;
void dfs(int cnt,ll sum1,ll sum2){
if (cnt==15){
if (abs(sum1-sum2)<mini) mini=abs(sum1-sum2);
return ;
}
dfs(cnt+1,sum1+in[cnt],sum2);
dfs(cnt+1,sum1,sum2+in[cnt]);
}
int main(){
for (int i=0;i<15;i++) cin>>in[i];
dfs(0,0,0);
cout<<mini;
return 0;
}
D、矩阵
把1-2020放在2*1010的矩阵中,要求同一行中右面的数比左面的大,同一列中下面的数比上面的大。一共有多少种方案?求其模2020后的结果。
1340:参考大佬的码学习dp:dp[i][j]表示前i个数有j个在第一行,初始条件dp[1][1]=1,迭代条件是dp[i][j]+=dp[i-1][j-1](肯定可以放上一行),若底下的数个数少于上面数的个数还可以往下面填充,则dp[i][j]+=dp[i-1][j]
int dp[maxn+1][maxn+1];//前i个数放j个到第一行
int main(){
memset(dp,0,sizeof(dp));
dp[1][1]=1;//1必放在左上角
for (int i=2;i<=maxn;i++){
for (int j=1;j<=i;j++){
dp[i][j]=(dp[i][j]+dp[i-1][j-1])%maxn;
if (i-j<=j){//放到第二行的数字少于放到第一行的数字
dp[i][j]=(dp[i][j]+dp[i-1][j])%maxn;
}
}
}
cout<<dp[maxn][maxn/2];
return 0;
}
E、完美平方数
如果整个整数X本身是平方数,其每一位数字也是平方数,则其为完美平方数。前几个完美平方数为:0、1、4、9、49、100、144…请问第2020个完美平方数是多少?
5555我太菜了不会写,只能copy大佬的码了
运行了半个小时才结束,不知道出来的是什么数字。。。
typedef long long ll;
int main(){
ll cnt=1390,t,n=sqrt(1919014494944411009),num[4]={0,1,4,9};
while (cnt<2020){
t=n*n;
while (t){
if (t%10!=0&&t%10!=1&&t%10!=4&&t%10!=9) break;
else t/=10;
}
if (t==0){
cnt+=1;
cout<<cnt<<" "<<n*n<<endl;
}
n+=1;
}
return 0;
}
2020年省A第二场
A、门牌制作
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?
624:遍历
int main(){
int cnt=0,x;
for (int i=1;i<2021;i++){
x = i;
while (x){ //找2
if (x%10==2) cnt+=1;
x/=10;
}
}
cout<<cnt;
return 0;
}
B、即约分数
如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。例如, 3/4 , 5/2 , 1/8 , 7/1 都是既约分数。请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1和 2020)?
2481215:最大公因数基础题,没啥好说的
int gcd(int x,int y){return y?gcd(y,x%y):x;};
int main(){
int cnt=2020*2-1; //含1的分数
for (int i=2;i<2021;i++){
for (int j=2;j<2021;j++){
if (gcd(i,j)==1) cnt+=1;
}
}
cout<<cnt;
return 0;
}
C、蛇形填数
如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 …
3 5 8 14 …
4 9 13 …
10 12 …
11 …
…
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列。
761:只看对角线 (1,1)=0+1,(2,2)=1+4,(3,3)=4+9…(20,20)=19*19+20*20
D、跑步锻炼
正常情况下小蓝每天跑1km,如果某天是周一或月初(1日), 小蓝要跑2千米。如果同时是周一或月初,小蓝也是跑2千米。从2000年1月1日周六(含)到 2020年10月1日周四(含)。请问这段时间小蓝总共跑步多少千米?
思路: 数组存储每月天数,int存储当前月份、星期,从2000.1.1到2020.10.1遍历,仔细判断。
int main(){
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int sum=0,day=6;
for (int i=2000;i<2021;i++){
//平润年2月天数不同
if (i%4==0) month[2]=29;
else month[2]=28;
int maxi,nowM=1,cnt=1;//最大月份,1月,1日
int run; //每天跑多少
if (i!=2020) maxi=13;
else maxi=10;
while (nowM<maxi){
while (cnt<=month[nowM]){//每个月
run=1;
if (day==8) day=1;//换星期
if (cnt==1||day==1) run=2;//1号或星期1
cnt+=1;
day+=1;
sum+=run;
}
cnt=1;
nowM+=1;
}
}
cout<<sum+2; //10月1日肯定跑2km
return 0;
}
E、七段码(DFS+并查集/穷举/暴力遍历)
数码管中一共有 7 段可以发光的二极管,分别标记为 a, b, c, d, e, f, g。小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。例如:b 发光,其他二极管不发光可以用来表达一种字符。例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。请问,小蓝可以用七段码数码管表达多少种不同的字符?
80:数/遍历+条件/DFS+并查集
1、a,b,c,d,e,f,g:7种
2、ab,af,bc,bg;cd,cg,de,ef,eg,fg; 10种
3、abc,abf,abg,aef,afg,bcd,bcg,beg,bfg,
cde,cdg,ceg,cfg,def,deg,efg:16种
4、abcd,abcf,abcg,abef,abeg,abfg,acfg;
adef,aefg,bcde,bcdg,bceg,bcfg,bdeg,befg;
cdef,cdeg,cdfg,cefg,defg;:20种
5、abcde,abcdf,abcdg,abcef,abceg,abcfg,abdef,
abdeg,abefg,acdef,acdfg,acefg,adefg,bcdef,
bcdeg,bcdfg,bcefg,bdefg,cdefg; 19种
6、abcdef,abcdeg,abcdfg,abcefg,abdefg,acdefg,
bcdefg;7种
7、abcdefg 1种
总数:7+10+16+20+19+7+1= 80;
int main(){
int a,b,c,d,e,f,g,res=0;
for (a=0;a<2;a++){
for (b=0;b<2;b++){
for (c=0;c<2;c++){
for (d=0;d<2;d++){
for (e=0;e<2;e++){
for (f=0;f<2;f++){
for (g=0;g<2;g++){
if ((a==0||(a==1&&(b==1||f==1)))
&& (b==0||(b==1&&(a==1||g==1||c==1)))
&& (c==0||(c==1&&(b==1||g==1||d==1)))
&& (d==0||(d==1&&(c==1||e==1)))
&& (e==0||(e==1&&(d==1||g==1||f==1)))
&& (f==0||(f==1&&(e==1||g==1||a==1)))
&& (g==0||(g==1&&(f==1||b==1||e==1||c==1)))){
if (a+b+c+d+e+f+g>0) res+=1;//不是全灭
else break;
}
}
}
}
}
}
}
}
cout<<res+7-3;//加上单个发光,减去abde afcd bcef这种两个 两个连起来的
return 0;
}
int use[10],ans,e[10][10],head[10];
void init(){//哪些点相连
e[1][2]=e[1][6]=1;
e[2][1]=e[2][7]=e[2][3]=1;
e[3][2]=e[3][4]=e[3][7]=1;
e[4][3]=e[4][5]=1;
e[5][4]=e[5][6]=e[5][7]=1;
e[6][1]=e[6][5]=e[6][7]=1;
e[7][2]=e[7][3]=e[7][5]=e[7][6]=1;
}
int f(int x){
if(head[x]==x) return x;
return head[x]=f(head[x]);
}
void dfs(int cnt){
if (cnt>7){//并查集判是否在同一集合
for (int i=1;i<=7;i++) head[i]=i;//初始化根节点
for (int i=1;i<=7;i++){//遍历所有边
for(int j=1;j<=7;j++){
if(e[i][j]&&use[i]&&use[j]){//i和j相邻且都亮
int x=f(i),y=f(j);
if(x!=y) head[x]=y;//合并
}
}
}
int fa=0;
for (int i=1;i<=7;i++){
if(use[i]&&head[i]==i) fa++;
}
if(fa==1) ans++;//合法
return;
}
use[cnt]=1;//打开这个灯
dfs(cnt+1);
use[cnt]=0;//关掉这个灯
dfs(cnt+1);
}
int main(){
init();
dfs(1);
cout<<ans;
}
E、斐波那契数列最大公约数
6765:第一眼好简单,结果是大整数问题。大整数写起来好麻烦而且这是第一道大题哎,所以搜到定理GCD(F[2020],F[520])=F[GCD(2020,520)],于是交换求解顺序使问题简单化。
typedef long long ll;
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;};
int main(){
ll F[2021],res=gcd(2020,520);
F[1]=F[2]=1;
for (ll i=3;i<2021;i++) F[i]=(F[i-1]+F[i-2]);
cout<<F[res];
return 0;
}