蓝桥杯选做

1|0杂项


1|1错误票据【第四届】【省赛】


#include <bits/stdc++.h> using namespace std; int n; vector<int> a; int main() { int n , m ; string s; cin >> n; getchar(); for( int i = 1 ; i <= n ; i ++ ) { getline( cin , s ) , m = 0; for( int t = 0; t <= s.size() - 1 ; t ++ ) { if( s[t] == ' ' ) { a.push_back( m ); m = 0; } else m = m * 10 + s[t] - '0'; } a.push_back(m); } sort( a.begin() , a.end() ); for( int i = 0 ; i < a.size() - 1 ; i ++ ) { if( a[i] + 1 != a[ i + 1 ] && a[i] != a[ i + 1 ] ) n = a[ i ] + 1; if( a[i] == a[ i + 1 ] ) m = a[i]; } cout << n << " " << m << endl; return 0; }

1|2翻硬币【第四届】【省赛】


#include <bits/stdc++.h> using namespace std; int cnt; string a , b; int main() { cin >> a >> b; for( int i = 0 ; i < a.size() ; i ++ ) { if( a[i] == b[i] ) continue; cnt ++; a[i] = ( a[i] == 'o' ? '*' : 'o' ); a[ i + 1 ] = ( a[ i + 1 ] == 'o' ? '*' : 'o' ); } cout << cnt << endl; return 0; }

2|02020年C++省赛 B 组


2|1门牌制作


624

2|2即约分数


2481215

2|3蛇形填数


打表代码

#include <bits/stdc++.h> using namespace std; const int N = 50; int a[N][N]; int main(){ int k = 1; for( int i = 1 ; i <= 50 ; i ++ ) { if( i & 1) for( int j = 1 ; j <= i ; j ++ ) a[i][j] = k , k ++; else for( int j = i ; j >= 1 ; j -- ) a[i][j] = k , k ++; } for( int i = 1 ; i <= 5 ; i ++ ) { for (int j = 1; j <= 5 ; j++) printf("%4d" , a[i+j-1][j] ); cout << endl; } cout << a[39][20] << endl; }

答案

761

2|4七段码


打表代码

就是用 dfs 枚举出所有的情况,再用并查集判断是否在同一个集合中

#include <bits/stdc++.h> using namespace std; const int N = 10; int res, fa[N]; bool e[N][N] , use[N]; int getfa( int x ) { if( fa[x] == x ) return x; return fa[x] = getfa( fa[x] ); } void merge( int x , int y ) { x = getfa(x) , y = getfa(y); fa[x] = y; return ; } void dfs( int d ) { if( d > 7 ){ for( int i = 1 ; i <= 7 ; i ++ ) fa[i] = i; for( int i = 1 ; i <= 7 ; i ++ ) for( int j = 1 ; j <= 7 ; j ++ ) if( e[i][j] && use[i] && use[j] ) merge( i , j ); int k = 0; for( int i = 1 ; i <= 7 ; i ++ ) if( use[i] && fa[i] == i ) k ++; if( k == 1 ) res ++; return; } dfs(d+1); use[d] = 1; dfs(d+1); use[d] = 0; return ; } int main() { e[1][2] = e[1][6] = 1; e[2][1] = e[2][3] = e[2][7] = 1; e[3][7] = e[3][4] = e[3][2] = 1; e[4][3] = e[4][5] = 1; e[5][4] = e[5][6] = e[5][7] = 1; e[6][1] = e[6][7] = e[6][1] = 1; dfs(1); cout << res << endl; }

2|5跑步锻炼


8879

打表代码

year = 2000 month = 1 date = 1 cnt = 0 week = 6 while 1 : cnt += 1 if( date == 1 or week == 1 ): cnt += 1 if year == 2020 and month == 10 and date == 1: break week += 1 if week == 8 : week = 1 date += 1 if ( month == 1 or month == 3 or month == 5 or month == 7 or month == 8 or month == 10 or month == 12 ) and date == 32: date = 1 month += 1 elif ( year == 2000 or year == 2004 or year == 2008 or year == 2012 or year == 2016 or year == 2020 ) and month == 2 and date == 30 : month += 1 date = 1 elif not ( year == 2000 or year == 2004 or year == 2008 or year == 2012 or year == 2016 or year == 2020 ) and month == 2 and date == 29 : date = 1 month += 1 elif not( month == 1 or month == 3 or month == 5 or month == 7 or month == 8 or month == 10 or month == 12 or month == 2 ) and date == 31: date = 1 month += 1 if month == 13 : month = 1 year += 1 print(cnt)

2|6成绩统计


签到题

#include <iostream> #include <cstring> #include <algorithm> using namespace std; int n , a , b; int main() { cin >> n; for( int i = 1 , x ; i <= n ; i ++ ) { cin >> x ; if( x >= 60 ) a ++; if( x >= 85 ) b ++; } printf("%.0lf%%\n%.0lf%%\n" , 100.0*a/n , 100.0*b/n ); }

2|7子串分值和


60 分

就是枚举起点和终点,然后统计一下就好

#include <bits/stdc++.h> using namespace std; const int N = 1e5+5 , M = 30; int n , res , cnt ; string s; bool vis[M]; int main() { cin >>s; n = s.size(); for( int i = 0 ; i < n ; i ++ ) { memset( vis , 0 , sizeof(vis) ); cnt = 0; for( int j = i , t ; j < n ; j ++ ) { t = s[j] - 'a'; if( !vis[t] ) cnt ++ , vis[t] = 1; res += cnt; } } cout << res << endl; }

100分

在上面的基础上,如果[i,j]有 26 个字母那么[i,j+1]也是 26 个后面的每一个都是 26 个没必要继续循环下去

#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e5+5 , M = 30; int n ; ll res , cnt ; string s; bool vis[M]; int main() { cin >>s; n = s.size(); for( int i = 0 ; i < n ; i ++ ) { memset( vis , 0 , sizeof(vis) ); cnt = 0; for( int j = i , t ; j < n ; j ++ ) { t = s[j] - 'a'; if( !vis[t] ) cnt ++ , vis[t] = 1; if( cnt == 26 ) { res += ( n - j ) * cnt; break; } res += cnt; } } cout << res << endl; }

但是这个做法没有通过 acw 的加强数据

正解

就是 dp , f[i]表示右端点为i的所有区间的和,如果s[i+1]在1到i中最后一次出现的位置是p那么f[i+1]=f[i]+i-p,因为 p之后的每一个区间都要加一

#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e5+5 , M = 30; int n , pos[N]; ll res , f[N]; char s[N]; int main() { scanf("%s" , s+1 ); n = strlen(s+1); for( int i = 1 , t; i <= n ; i ++ ) t = s[i] - 'a' , f[i] = f[i-1] + i - pos[t] , pos[t] = i , res += f[i]; cout << res << endl; }

2|8回文日期


这题就是首先向枚举日期,再进行判断

这里有一个问题是,b 一定是 a,a 不一定是 b 且,b不等于 a,所以可以推断 b>a,证明可以用反证法

#include <bits/stdc++.h> #define ll long long using namespace std; int n; int months[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; bool check_date( int x ) { int year = x/10000 , month = x%10000/100 , day = x%100; if(!day || month < 1 || month > 12 ) return 0; if( month != 2 && day > months[month] ) return 0; if( month == 2 ){ if( year%4==0 && year%100!=0 || ( year%400==0) ) { if(day>29) return 0; } else{ if(day>28) return 0; } } return 1; } bool check1(string s){ int len = s.size(); for( int i = 0 , j = len - 1 ; i < j ; i ++ , j -- ) if( s[i] != s[j] ) return 0; return 1; } bool check2(string s){ if(!check1(s)) return 0; if( s[0]!= s[2] || s[1]!=s[3] || s[0] == s[1] ) return 0; return 1; } void slove() { cin >> n; for( int i = n+1 , flag = 0 ; ; i ++ ) { if( !check_date(i) ) continue; string s = to_string(i); if( check1(s) && !flag ) { cout << i << endl; flag = 1; } if(check2(s)) { cout << i << endl; return ; } } } int main() { int t; cin >> t; while( t-- ) slove(); return 0; }

2|9平面切分


每增加一条线,区域数就会加一,当前线与之前每多一个交点区域数也会加一

#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1005; int n , m , cnt = 1; pair< int , int > e[N]; set< pair<double,double> > s; int read(){ int x = 0 , f = 1 , ch = getchar(); while( (ch<'0'||ch>'9') && ch != '-' ) ch = getchar(); if( ch == '-' ) f = -1 , ch = getchar(); while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1) + ch-'0' , ch = getchar(); return x*f; } int main() { m = n = read(); for( int i = 1 ; i <= n ; i ++ ) e[i].first = read() , e[i].second = read(); sort( e+1 , e+1+n ); n = unique( e+1 , e+1+n ) - e - 1; double nx , ny ; for( int i = 1 ; i <= n ; i ++ ){ s.clear() , cnt ++; for( int j = 1 ; j < i ; j ++ ) if( e[i].first != e[j].first ) nx = 1.0*(e[i].second-e[j].second)/(e[j].first-e[i].first) , ny = e[i].first*nx+e[i].second , s.insert({nx,ny}); cnt += s.size(); } cout << cnt << endl; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/16125460.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示