蓝桥杯模拟赛3
A-特殊年份
签到吧
#include <bits/stdc++.h>
using namespace std;
int32_t main(){
string s;
int cnt = 0;
for( int i = 1 ; i <= 5 ; i ++ ){
cin >> s;
if( s[0] == s[2] && s[3] - s[1] == 1 ) cnt ++;
}
cout << cnt << "\n";
}
B-小平方
为了规避浮点数运算可以把除法变成乘法
#include <bits/stdc++.h>
using namespace std;
int32_t main(){
int n , res = 0;
cin >> n;
for( int i = 1 , t ; i < n ; i ++ ){
t = ( i * i ) % n;
if( t * 2 < n ) res ++;
}
cout << res << "\n";
}
C-砝码称重
f[i][j]
表示前i
个砝码能否称重质量j
,如果f[i-1][j]=1
则f[i][j+w]=f[i][abs(j-2)]=1
,复杂度\(O(nm)\)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5 , M = 105;
int n , f[M][N] , res ;
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;
}
int32_t main() {
n = read();
f[0][0] = 1;
for( int w , i = 1 ; i <= n ; i ++ ){
w = read();
for( int j = 0 ; j < N ; j ++ ){
if( f[i-1][j] ) f[i][j] = f[i][j+w] = f[i][ abs(j-w) ] = 1;
}
}
for( int i = 1 ; i < N ; i ++ ) res += f[n][i];
cout << res ;
}
D-完全平方数
把数字进行质因数分解,把奇数次方的质数求乘积就是答案,复杂度\(O(\sqrt n)\)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main() {
int n, res = 1;
cin >> n;
for( int i = 2 , m = sqrt(n) , cnt ; i <= m && n > 1 ; i ++ ){
if( n % i ) continue;
cnt = 0;
while( n % i == 0 ) cnt ++ , n /= i;
if( cnt & 1 ) res *= i;
}
if( n > 1 ) res *= n;
cout << res ;
return 0;
}
E-时间显示
首先要知道\(1s=10^3 ms\),其次是直接舍弃毫秒不是四舍五入。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main() {
int t , h , m , s;
cin >> t;
t /= 1000;
s = t % 60 , t /= 60;
m = t % 60 , t /= 60;
h = t % 24 , t /= 24;
printf("%02d:%02d:%02d\n" , h , m , s );
return 0;
}
F-杨辉三角形
杨辉三角左右完全对称,所以答案一定是在左半边。
我们侧着看每一个斜行内一定是单调递增的,且斜行之间也一定是单调递增的。比如第三斜行的第一个数6在第二斜行总出现的位置一定是更靠后,为什么?因为第三斜行的6所在的横放是1,4,6
,所以对应的第二斜行的位置是4,所以6在第二斜行出现一定更靠后。
且第k斜行的数是\(C_{2k}^{k},C^{k+1}_{2k},C_{2k}^{k+2}\cdots\),所以在斜行内可以二分。并且\(C_{34}^{17}>1e9\),所以数字一定出现在前16个斜行中。我们直接在每一个斜行中二分即可。复杂度\(O(\log n)\)
# include <bits/stdc++.h>
using namespace std;
#define int long long
int n;
int C(int x, int y) {
y = min(y, x - y);
int res = 1;
for (int i = x, j = 1; j <= y; i--, j++){
res = res * i / j;
if( res > n ) return res;
}
return res;
}
int check( int k ){
int l = k * 2 , r = max( n , l ) , mid , res ;
while( l <= r ){
mid = ( l + r ) >> 1;
if( C( mid , k ) >= n ) res = mid , r = mid - 1;
else l = mid + 1;
}
if( C(res,k) != n ) return -1;
return ( 1 + res ) * res / 2 + k + 1 ;
}
int32_t main() {
cin >> n;
for( int i = 16 , t ; ; i -- ){
t = check(i);
if( t == -1 ) continue;
cout << t;
return 0;
}
return 0;
}
G-左孩子右兄弟
对于每一个点的儿子最优放置方法是子树转换成二叉树后子树深度最深的儿子最后放。
所以每一个点的子树转换成二叉树的最大深度就是:儿子的子树转换成二叉树后的最大深度+点儿子的个数
复杂度\(O(n)\)
#include <bits/stdc++.h>
using namespace std;
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;
}
const int N = 1e5+5;
vector<int> e[N];
int dfs( int u ){
int res = 0 , t = e[u].size() ;
for( auto v : e[u] ) res = max( res , dfs(v) + t );
return res;
}
int main(){
int n = read();
for( int v = 2 , u ; v <= n ; v ++ ) u = read() , e[u].push_back(v);
cout << dfs( 1 );
}
H-负载均衡
对于每一台电脑用优先队列维护一下正在计算的任务,按照结束时间排序。每次执行任务前把所有已经结束的任务出队,然后更新当前计算机的剩余算力。复杂度\(O(m\log\frac{m}{n})\)
#include <bits/stdc++.h>
using namespace std;
#define int long long
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;
}
int32_t main() {
int n = read(), m = read();
vector<int> v(n);
for (int &i: v) i = read();
vector<priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>> que(n);
for (int a, b, c, d; m; m--) {
a = read(), b = read() - 1, c = read(), d = read();
while (!que[b].empty() && que[b].top().first <= a) v[b] += que[b].top().second, que[b].pop();
if (v[b] < d) {
printf("-1\n");
continue;
}
v[b] -= d, que[b].emplace(a + c, d);
printf("%lld\n", v[b]);
}
return 0;
}