day1 哼哼滴冲
一想到蓝桥杯还有一个月,自己还在召唤师峡谷,苦练剑魔,青钢影,我就有一种开摆的快乐,(不,亚达哟,从今天开始做做真题吧,希望蓝桥杯不要寄
空间 - 蓝桥云课 (lanqiao.cn)
#include
using namespace std;
int main()
{
cout<<256 * 1024 * 1024 / 4 <<endl;
return 0;
}
// 答案: 67108864
---------------------------------分割线----------------------------------
1 MB = 1024 KB
1 KB = 1024 B
1 Byte = 8 bit
#include
using namespace std;
const int N = 10;
int cnt[N];
int main()
{
for(int i = 0 ; i <= 9 ; i++) cnt[i] = 2021;
int res = 1;
bool flag = true;
for(; flag ; res++)
{
flag = true;
auto t = res;
while(t)
{
cnt[t % 10]--;
if(cnt[t % 10] == 0)
{
flag = false;
break;
}
t /= 10;
}
}
cout<<res - 1<<endl;
}
// 答案: 3181
---------------------------------分割线----------------------------------
直接嗯造
没有发现题目链接
---------------------------------分割线----------------------------------
注意double有精度差,我们用斜率 + 截距就行判断,还要加上20条竖线,初始res为1是因为,没有直线和它比较
#include
#include
using namespace std;
const int N = 200000;
int n;
struct Line
{
double k,b;
bool operator< (const Line &t) const
{
if(k != t.k) return k < t.k;
return b < t.b;
}
}l[N];
int main()
{
for(int x1 = 0 ; x1 < 20 ; x1++)
for(int y1 = 0 ; y1 < 21 ; y1++)
for(int x2 = 0 ; x2 < 20 ; x2++)
for(int y2 = 0 ; y2 < 21 ; y2++)
if(x1 != x2)
{
double k = (double) (y2 - y1 ) / (x2 - x1);
double b = y2 - k * x2;
l[n++] = {k,b};
}
sort(l,l + n);
int res = 1;
for(int i = 1 ; i < n ; i++)
if(l[i].k - l[i-1].k > 1e-8 || l[i].b - l[i-1].b > 1e-8)
res ++;
cout<<res + 20 <<endl;
return 0;
}
// 答案:40257
---------------------------------分割线----------------------------------
先预处理约数…,然后暴力,就完了,之前的真暴力做法TLE了,顺便注意下爆int就行
#include
#include
using namespace std;
typedef long long LL;
int main()
{
LL n = 2021041820210418;
vector<LL> d;
// 预处理约数
for(LL i = 1 ; i * i <= n ; i++)
if(n % i == 0)
{
d.push_back(i);
if(n / i != i) d.push_back(n / i);
}
int res = 0;
// 枚举
for(auto a : d)
for(auto b : d)
for(auto c : d)
if(a * b * c == n)
res ++;
cout<<res<<endl;
return 0;
}
// 答案:2430
路径 - 蓝桥云课 (lanqiao.cn)
---------------------------------分割线----------------------------------
我们用Dijkstra来做,y总用spfa,就是要不一样
#include
#include
#include
using namespace std;
const int N = 2200;
int n,m;
int g[N][N];
int dist[N];
bool st[N];
int gcd(int a,int b) // 返回最大公约数
{
return b ? gcd(b, a % b) : a;
}
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1] = 0;
for(int i = 0 ; i < n - 1 ; i++)
{
int t = -1;
for(int j = 1 ; j <= n ; j++)
if(!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
for(int j = 1 ; j <= n ; j++)
dist[j] = min(dist[j],dist[t]+g[t][j]);
st[t] = true;
}
if(dist[n] == 0x3f3f3f3f) return -1;
return dist[n];
}
int main()
{
n = 2021;
memset(g,0x3f,sizeof g);
for(int i = 1 ; i <= n ; i++)
for(int j = max(1,i - 2) ; j <= min(n,i + 21) ; j++)
{
int d = gcd(i , j);
g[i][j] = i * j / d; // 嗨呀!原来a和b的最小公倍数等于 a * b 除以它们的最大公约数
}
cout<<dijkstra()<<endl;
return 0;
}
// 答案:10266837
时间显示 - 蓝桥云课 (lanqiao.cn)
【样例输入1】
4680099
【样例输出1】
13:00:00
【样例输入2】
1618708103123
【样例输出2】
01:08:23
【评测用例规模与约定】
对于所有评测用例,给定的时间为不超过 1 0 18 10^{18} 1018的正整数
---------------------------------分割线----------------------------------
正常题,就是注意下会爆int
#include
using namespace std;
int main()
{
long long n;
cin>>n;
n /= 1000;
n %= (3600 * 24);
int hours = n / 3600;
int minutes = n % 3600 / 60;
int seconds = n % 60;
printf("%02d:%02d:%02d",hours,minutes,seconds);
return 0;
}
砝码称重 - 蓝桥云课 (lanqiao.cn)
【样例输入】
3
1 4 6
【样例输出】
10
【样例说明】
能称出的10种重量是:1、2、3、4、5、6、7、9、10、11。
1=1
2=6-4(天平一边放6,另一边放4)
3=4-1;
4=4
5=6-1
6=6
7=6+1
9=4+6-1
10=4+6
11=1+4+6
【评测用例规模与约定】
对于 50% 的评测用例,1 ≤ \le ≤ N ≤ \le ≤ 15;
对于所有的评测用例: 1 ≤ \le ≤ N ≤ \le ≤ 100,N个砝码总重量不超过100000;
---------------------------------分割线----------------------------------
有限制的选择问题(背包问题)
来到了我们闫氏DP分析法了嗷,集合划分,最后一个砝码放到哪边有三种情况
之后考虑f[n][1~m]
有多少个非空就行(m为总重量),因为j的范围为-m ~ + m
数组没有负数下标,所以我们要加上偏移量B
#include
using namespace std;
const int N = 110,M = 200010,B = M / 2;
bool f[N][M];
int w[N];
int n,m;
int main()
{
cin>>n;
for(int i = 1 ; i <= n ; i++) cin>>w[i],m += w[i];
f[0][B] = true;
for(int i = 1 ; i <= n ; i++)
for(int j = -m ; j <= m ; j++)
{
f[i][j+B] = f[i-1][j+B];
if(j - w[i] >= -m) f[i][j+B] |= f[i-1][j - w[i] + B];
if(j + w[i] <= m) f[i][j+B] |= f[i-1][j + w[i] + B];
}
int res = 0;
for(int i = 1 ; i <= m ; i++)
if(f[n][i+B])
res++;
cout<<res<<endl;
return 0;
}
杨辉三角形 - 蓝桥云课 (lanqiao.cn)
【输入样例】
6
【输出样例】
13
【评测用例规模与约定】
对于 20% 的评测用例,1 ≤ \le ≤ N ≤ \le ≤ 10;
对于所有的评测用例: 1 ≤ \le ≤ N ≤ \le ≤ 1000000000;
---------------------------------分割线----------------------------------
找规律题目,因为对称,并且要找的数字是第一次出现的,所以我们只要找左边就行了
我们不难发现, C 36 17 C_{36}^{17} C3617 就结束了,超过1e9 了,所以枚举1~16行就差不多了,由于是递增的,所以我们可以用二分查查在哪里
#include
#include
#include
using namespace std;
typedef long long LL;
int n;
LL C(int a,int b)
{
LL res = 1;
for(int i = a , j = 1 ; j <= b ; i -- , j ++)
{
res = res * i / j;
if(res > n) return res;
}
return res;
}
bool check(int k)
{
LL l = k * 2 , r = max((LL)n,l);
while(l < r)
{
LL mid = l + r >> 1;
if(C(mid,k) >= n) r = mid;
else l = mid + 1;
}
if(C(r,k) != n) return false;
cout << r * (r + 1) / 2 + k + 1 << endl;
return true;
}
int main()
{
cin>>n;
for(int k = 16 ; ; k--)
if(check(k))
break;
return 0;
}
双向排序 - 蓝桥云课 (lanqiao.cn)
【输入样例】
3 3
0 3
1 2
0 2
【输出样例】
3 1 2
【样例说明】
原数列为(1,2,3)
第1步后为(3,2,1)
第2步后为(3,1,2)
第3步后为(3,1,2)。与第2步操作后相同,因为前两个数已经是降序了。
【评测用例规模与约定】
对于 30% 的评测用例,n,m ≤ \le ≤ 1000 ;
对于 60% 的评测用例,n,m ≤ \le ≤ 5000 ;
对于所有的评测用例: 1 ≤ \le ≤ n,m ≤ \le ≤ 100000,0 ≤ \le ≤ p i p_i pi ≤ \le ≤ 1,1 ≤ \le ≤ q i q_i qi ≤ \le ≤ n 。
---------------------------------分割线----------------------------------
Splay,人已麻,目前对我来说没有学习意义,不如考试sort写暴力,直接开摆
括号序列 - 蓝桥云课 (lanqiao.cn)
【样例输入】
((()
【样例输出】
5
【评测用例规模与约定】
对于 40% 的评测用例,|s| ≤ \le ≤ 200 ;
对于所有的评测用例: 1 ≤ \le ≤ |s| ≤ \le ≤ 5000;
---------------------------------分割线----------------------------------
这题,真叫我写暴力,我都不知道怎么写,真哈人
合法的括号序列,需要满足两个条件
我们会发现,左括号和右括号,可以分开考虑
添加左括号,添加右括号的方案相乘就是答案
如何保证添加方案不重复
如果我们现在添加左括号,如上图,我们可以以右括号为分界,划分出四个区间。我们规定,只在右括号的前面添加任意多的左括号
闫氏DP开始
所以
f[i][j] = f[i-1][j+1] + f[i-1][j] + ... + f[i-1][0];
// 优化下
f[i][j-1]=f[i][j]+f[i-1][j-1]+...+f[i-1][0];
// 因此
f[i][j] = f[i-1][j+1] + f[i][j-1];
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 5010, MOD = 1e9 + 7;
int n;
char str[N];
LL f[N][N];
LL work()
{
memset(f, 0, sizeof f);
f[0][0] = 1;
for (int i = 1; i <= n; i ++ )
if (str[i] == '(')
{
for (int j = 1; j <= n; j ++ )
f[i][j] = f[i - 1][j - 1];
}
else
{
f[i][0] = (f[i - 1][0] + f[i - 1][1]) % MOD;
for (int j = 1; j <= n; j ++ )
f[i][j] = (f[i - 1][j + 1] + f[i][j - 1]) % MOD;
}
for (int i = 0; i <= n; i ++ )
if (f[n][i])
return f[n][i];
return -1;
}
int main()
{
scanf("%s", str + 1);
n = strlen(str + 1);
LL l = work();
reverse(str + 1, str + n + 1);
for (int i = 1; i <= n; i ++ )
if (str[i] == '(') str[i] = ')';
else str[i] = '(';
LL r = work();
printf("%lld\n", l * r % MOD);
return 0;
}
我的评价是太麻了,真让我考,我真的寄寄了,蓝桥杯一点都不水,是我自己
视频链接