[蓝桥杯2020初赛] 门牌制作
Tag
数学
题意
1
到 2020
一共有多少字符 2
#include<iostream>
using namespace std;
int ans;
int main(){
for(int i=1;i<=2020;i++){
int t=i;
while(t){
if(t%10==2)ans++;
t/=10;
}
}
cout<<ans<<endl;
return 0;
}
[蓝桥杯2020初赛] 既约分数
Tag
gcd
题意
一个分数的分子和分母的最大公约数是 1
,这个分数称为既约分数,求 1
到 2020
有多少既约分数
#include<iostream>
using namespace std;
int ans;
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int main(){
for(int i=1;i<=2020;i++)
for(int j=i+1;j<=2020;j++)
if(gcd(i,j)==1)ans++;
cout<<ans*2+1<<endl; // 1/1 特判
return 0;
}
[ 蓝桥杯2020初赛] 蛇形填数
Tag
数学
1 2 6 7 15 ...
4 5 8 14 ...
4 9 13 ...
10 12 ...
11 ...
...
题意
求第 20
行 20
列的数
#include<iostream>
using namespace std;
int main(){
cout<<38*39/2+20<<endl;
return 0;
}
[蓝桥杯2020初赛] 七段码
Tag
并查集
![img](https://i-blog.csdnimg.cn/blog_migrate/b36b2b772a7a7c5efd94bd953eaca966.webp?x-image-process=image/format,png)
题意
有多少种连成一片的表达字符的方案(只亮 b
和 只亮 c
算一种)。
每条边代表的代号
1
6 2
7
5 3
4
#include<iostream>
#include<cstring>
#define endl '\n'
using namespace std;
const int N=8;
int g[N][N];
int p[N];
bool st[N];
void add(int a,int b){
g[a][b]=g[b][a]=1;
}
int find(int x){
if(x!=p[x])p[x]=find(p[x]);
return p[x];
}
void init(){
add(1,2),add(1,6);
add(2,7),add(6,7);
add(2,3),add(5,6);
add(5,7),add(3,7);
add(3,4),add(4,5);
}
int main(){
init();
int ans=0;
for(int i=1;i<1<<7;i++){
memset(st,0,sizeof st);
for(int j=1;j<=7;j++)p[j]=j;
for(int j=0;j<7;j++)
if((i>>j)&1)st[j+1]=1;
for(int j=1;j<=7;j++)
for(int k=1;k<=7;k++)
if(g[j][k]&&st[j]&&st[k]){
int pj=find(j);
int pk=find(k);
if(pj!=pk)p[pj]=pk;
}
int cnt=0;
for(int j=1;j<=7;j++)
if(st[j]&&p[j]==j)
cnt++; // 同为一个祖宗
if(cnt==1)ans++;
}
cout<<ans<<endl;
return 0;
}
[ 蓝桥杯2020初赛] 跑步锻炼
Tag
数学
题意
小蓝跑步,每天跑 1km
,若是每月初或每周一跑 2km
,问从 2000.1.1 周六
到 2020.10.1 周四
一共跑了多少千米(含两端点)
#include<iostream>
using namespace std;
const int M[2][12]={
{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}
};
bool flag=1;
int ans;
bool isPrime(int x){
return x%4==0&&x%100||x%400==0;
}
int main(){
int year=2000,month=0,day=0,week=5;
while(!(year==2020&&month==9&&day==1)){
if(day==0||week==0)ans++;
day++,ans++,week++;
week%=7;
if(day==M[flag][month]){
day=0;
month++;
if(month==12){
month=0;
year++;
flag=isPrime(year);
}
}
}
cout<<ans<<endl;
return 0;
}
[蓝桥杯2020初赛] 回文日期
Tag
数学
题意
n
个日期格式为 YYYYMMDD
,分别输出给定日期后的第一个回文日期和第一个 ABABBABA
格式的日期
#include<iostream>
#define endl '\n'
using namespace std;
const int month[2][12]={
{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}
};
bool isPrime(int x){
return x%4==0&&x%100||x%400==0;
}
bool check(int Y,int M,int D){
return M>0&&M<=12&&D>0&&D<=month[isPrime(Y)][M-1];
}
void solveA(int x,int y){
while(1){
int t=y;
int Y=0;
while(t){
Y=Y*10+t%10;
t/=10;
}
int M=Y/100,D=Y%100;
int ans=y*10000+M*100+D;
if(ans>x&&check(Y,M,D)){
cout<<ans<<endl;
return;
}
y++;
if(y%10==2)y+=8;
}
}
void solveB(int x,int y){
while(1){
int t=y;
int tr=t/10+t%10*10;
int res=t*1000000+t*10000+tr*100+tr;
int Y=t*100+t,M=tr,D=tr;
if(res>x&&check(Y,M,D)){
cout<<res<<endl;
return;
}
y++;
if(y%10==2)y+=8;
}
}
int main(){
int n;cin>>n;
while(n--){
int x;cin>>x;
solveA(x,x/10000);
solveB(x,x/1000000);
}
return 0;
}
[蓝桥杯2020初赛] 字串排序
题意
求出一个字符串依次按优先级满足以下条件:
- 通过冒泡排序经过
v
次交换 - 长度最短
- 字典序zui’xiao
[蓝桥杯2020初赛] 成绩统计
Tag
数学
题意
给定一个满分为 100
分的整数成绩,[60, 100]
为及格,[85,100]
为优秀,输出四舍五入的整数及格率和优秀率
#include<iostream>
#define endl '\n'
using namespace std;
int main(){
int n;cin>>n;
int r=0,R=0;
for(int i=0;i<n;i++){
int x;cin>>x;
if(x>=60)r++;
if(x>=85)R++;
}
cout<<int(1.0*r/n*100+0.5)<<'%'<<endl;
cout<<int(1.0*R/n*100+0.5)<<'%'<<endl;
return 0;
}
[蓝桥杯2020初赛] 子串分值和
Tag
dp
题意
求由小写字母组成的字符串的所有子字符串中不同字符的个数之和
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e5+2;
int dp[N],indx[26]; // indx[i] 表示前面有多少个 i 字符
string s;
ll res=0;
int main(void){
cin>>s;
for(int i=1;i<=s.size();i++){
int t=s[i-1]-'a';
dp[i]=dp[i-1]+i-indx[t];
res+=dp[i];
indx[t]=i;
}
cout<<res<<endl;
return 0;
}
[蓝桥杯2020初赛] 平面切分
Tag
数学
题意
n
条直线,求一共将平面切成了几个部分
#include<iostream>
#include<set>
#define mp make_pair
using namespace std;
set<pair<int,int>> line;
int res=1;
int search(int a,int b){ // 分区数 = 直线数 + 每次新增直线与已存在直线的交点 + 1
set<pair<double,double>> point;
for(auto i=line.begin();i!=line.end();i++){
int A=(*i).first,B=(*i).second;
if(a==A)continue;
double x=(b-B)*1.0/(A-a);
double y=a*x+b;
int old=point.size();
point.insert(mp(x,y));
}
return point.size();
}
int main(void){
int n;cin>>n;
while(n--){
int a,b;cin>>a>>b;
int l=line.size();
line.insert(mp(a,b));
if(l==line.size()||!l)continue;
res+=search(a,b);
}
cout<<res+line.size()<<endl;
return 0;
}