A: 门牌制作
小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字
符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、 0、 1、 7,即需要 1 个
字符 0, 2 个字符 1, 1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?
答案
624
暴力就完了
#include <bits/stdc++.h>
using namespace std;
int main(){
int res=0;
for(int i=1;i<=2020;i++){
int a=i;
while(a!=0){
int t=a%10;
if(t==2) res++;
a/=10;
}
}
cout<<res;
return 0;
}
B: 既约分数
如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。
例如都是既约分数。
请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1和 2020)?
答案
2481215
暴力+最大公约数
#include<iostream>
using namespace std;
int gcd(int a,int b){
if(b) return gcd(b,a%b);
return a;
}
int main(){
int res=0;
for(int i=1;i<=2020;i++){
for(int j=1;j<=2020;j++){
if(gcd(i,j)==1)res++;
}
}
cout<<res<<endl;
return 0;
}
C: 蛇形填数
如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 :::
3 5 8 14 :::
4 9 13 :::
10 12 :::
11 :::
:::
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少 ?
答案
761
模拟题,我开了两个布尔型的变量用来分别判断当前递增的方向,和是否已经换行(边界情况)
#include<iostream>
using namespace std;
int mp[50][50];
int main(){
bool a=true,b=false;
mp[1][1]=1;
int x=1,y=1;
for(int i=2;true;i++){
if((x==1||y==1)&&a){
if(x==1&&y==1){
mp[x][++y]=i;
}
else if(x==1){
mp[x][++y]=i;
}
else mp[++x][y]=i;
a=!a;
b=!b;
continue;
}
if(!a) a=!a;
if(b){
mp[++x][--y]=i;
}
else mp[--x][++y]=i;
if(x==25&&y==25) break;
}
cout<<mp[20][20]<<endl;
return 0;
}
D: 跑步锻炼
小蓝每天都锻炼身体。
正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初(1 日),为了
激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。
小蓝跑步已经坚持了很长时间,从2000年1月1日周六(含)到2020年10月1日周四(含)。请问这段时间小蓝总共跑步多少千米?
答案
8879
日期模拟
#include<iostream>
using namespace std;
int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int main(){
int y=2000,m=1,d=1,s=6,res=0;
while(!(y==2020&&m==10&&d==2)){
if(s==1||d==1) res+=2;
else res++;
d++;
s++;
if(s>7) s=1;
if((y%4==0&&y%100!=0)||y%400==0) day[2]=29;
else day[2]=28;
if(d>day[m]){
m++;
d=1;
if(m>12){
m=1;
y++;
}
}
}
cout<<res;
}
E: 七段码
有在想用并查集加DFS做,但是还没太想明白
空
F: 成绩统计
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int n;
cin>>n;
int acount=0;
int bcount=0;
for(int i=0;i<n;i++){
int score=0;
cin>>score;
if(score>=60) bcount++;
if(score>=85) acount++;
}
float a=floor(((acount*1.0)/n)*100+0.5);
float b=floor(((bcount*1.0)/n)*100+0.5);
cout<<b<<"%"<<endl<<a<<"%"<<endl;
}
G: 回文日期
可以模拟日期做,我是通过年份来判断,如果是这一年的话,回文数是多少(因为只要知道前四个数就可以推后四个数),判断这是不是合法日期,如果是,就采用,如果不是,就看下一年。
#include<iostream>
using namespace std;
int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int main(){
int n,res1,res2;
cin>>n;
int y=n/10000;
int d=n%100;
int m=(n/100)%100;
for(int i=y;true;i++){
int dd=((i/100)%10)*10+i/1000;
int dm=(i%10)*10+(i/10)%10;
if(dm>12) continue;
if((i%4==0&&i%100!=0)||i%400==0) day[2]=29;
else day[2]=28;
if(dd>day[dm]) continue;
if(i==y&&dd<=d&&dm<=m) continue;
res1=i*10000+dm*100+dd;
break;
}
for(int i=y;true;i++){
int a[5],t=i;
for(int i=0;i<4;i++){
a[i]=t%10;
t/=10;
}
if(a[0]!=a[2]||a[1]!=a[3]) continue;
if(a[0]==a[1]) continue;
//和上一段判断相同
int dd=((i/100)%10)*10+i/1000;
int dm=(i%10)*10+(i/10)%10;
if(dm>12) continue;
if((i%4==0&&i%100!=0)||i%400==0) day[2]=29;
else day[2]=28;
if(dd>day[dm]) continue;
if(i==y&&dd<=d&&dm<=m) continue;
res2=i*10000+dm*100+dd;
break;
}
cout<<res1<<endl<<res2<<endl;
}
H: 子串分值和
一个字符只有第一次出现时是有贡献的,记录a-z每一个字符上次在字符串中出现的位置,以此判断当前字符距离上一次出现中间多少字符,计算该字符作为第一次出现的子串数,它对这些子串都是有贡献的(即作为不同的字符出现)。
#include <iostream>
using namespace std;
int main()
{
long long chara[27]={0};
memset(chara,0,sizeof(chara));
string str;
cin>>str;
long long ans=0;
long long n=str.length();
for(long long i=0;i<n;i++){
char temp=str[i];
long long index=int(temp)-96;
ans+=(i-chara[index]+1)*(n-i);
chara[index]=i+1;
}
cout<<ans<<endl;
}