蓝桥杯选做
杂项
错误票据【第四届】【省赛】
#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;
}
翻硬币【第四届】【省赛】
#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;
}
2020年C++省赛 B 组
门牌制作
624
即约分数
2481215
蛇形填数
打表代码
#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
七段码
打表代码
就是用 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;
}
跑步锻炼
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)
成绩统计
签到题
#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 );
}
子串分值和
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;
}
回文日期
这题就是首先向枚举日期,再进行判断
这里有一个问题是,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;
}
平面切分
每增加一条线,区域数就会加一,当前线与之前每多一个交点区域数也会加一
#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;
}