2021年蓝桥杯题目整理
空间
256mb可以存多少32位的数据 答案:1byte = 8bit 所以256 * 1024 * 256 = 67108864
卡片
#include "iostream"
using namespace std;
int main()
{
int a[10] = { 2021,2021,2021,2021,2021,2021,2021,2021,2021,2021 };
int num = 0;
int flag = 1;
while (flag)
{
num++;
int t = num;
while (t)
{
a[t % 10]--;
if (a[t % 10] == 0)flag = 0;
t /= 10;
}
}
cout << num;
return 0;
}
答案:3181
直线
思路:每条不同的直线方程为ax+by+c=0,只要a,b,c(除以最小公约数)不一样就是不同的直线,
#include "iostream"
#include <vector>
#include <queue>
using namespace std;
int dp[25][25];
struct Node {
int a;
int b;
int c;
Node(int a1, int b1, int c1)
{
a = a1;
b = b1;
c = c1;
}
};//三元组定义
vector<Node>res;
bool find(Node num)//查找当前res中有没有新加入的三元组
{
for (int i = 0; i < res.size(); i++)
{
if (res[i].a == num.a&&res[i].b==num.b&&res[i].c==num.c)return true;
}
return false;
}
int gcd(int x, int y)
{
return !y ? x : gcd(y, x%y);
}
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n * m; i++)//减少循环次数,用i*j来区分行和列,遍历每个点
{
double x, y;
x = i % n;
y = (i-1) / n+1;//得出第一个点
for (int j = i; j <= n * m; j++)
{
if (x == 0)x = n;
double x1, y1;
x1 = j % n;
double k=0;
y1 = (j-1) / n+1;
if (x1 == 0)x1 = n;//得出第二个点
int a=0, b=0, c=0,t=0;
if (x != x1 && y != y1)
{
a = y1 - y;
b = (x1 - x);
c = (y - y1) * x1 + (x1 - x) * y;//两点确定一条直线的公式
t = gcd(a, b);
if (c % t == 0) {
a /= t;
b /= t;
c /= t;
}//最下公约数,确保不重合
}
Node* n = new Node(a, b, c);
if(!(n->a==0&&n->b==0&&n->c==0)&&!find(*n))
res.push_back(*n);
}
}
cout << res.size()+n+m;
return 0;
}
答案40257
货物摆放
思路:先取出所有的因子然后循环因子,记得开longlong
#include <iostream>
using namespace std;
typedef long long ll;
ll s[100005]; int index = 0;
int an = 0;
int main()
{
ll a = 2021041820210418;
ll cur = sqrt(a);//因子不会超过其平方,减少循环次数
for (ll i = 1; i <= cur; i++)
{
if (a % i == 0) {
s[index++] = i; s[index++] = a / i;//加入因子
}
}
for (int i = 0; i < index; i++)
{
for (int j = 0; j < index; j++)
{
for (int k = 0; k < index; k++)
{
if (s[i] * s[j] * s[k] == a)an++;
}
}
}
cout << an;
return 0;
}
答案2430
最短路径
思路:先填入数据,你要找里面的最小值,要先把数组全部赋值为无穷大0x3f,然后Floyd
#include <iostream>
using namespace std;
const int n = 2021;
int gcd(int x, int y)
{
return !y ? x : gcd(y, x % y);
}
int dp[n + 5][n + 5];
int main()
{
memset(dp, 0x3f, sizeof dp);//关键,填入无穷大
for (int i = 1; i <= n; i++)
{
dp[i][i] = 0;
for (int j = 1; j <= 21; j++)
{
dp[i + j][i] = dp[i][i + j] = (i * (i + j)) / gcd(i, i + j);//填入数据
}
}
for (int k = 1; k <= n; k++)//floyd算法
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (dp[i][k] + dp[k][j] < dp[i][j]) {//算小值现附上最大值
dp[i][j] = dp[i][k] + dp[k][j];//i-j的距离=i-k+k-j
}
cout << dp[1][n];
return 0;
}
答案10266837
砝码称重
思路:砝码只有三种状态,在左边,在右边,没放上去,我们深度搜索遍历所有情况,最后取绝对值就是可以量出来的数
输入数据:3 1 4 6 输出:10
#include <iostream>
using namespace std;
int ans = 0;
int a[1005];
int b[1005];
int c[1005];
int n;
int sumz = 0;//左边砝码重量
int sumy = 0;//右边砝码重量
int sum = 0;
void dfs(int u)
{
if (u == n) {//放完砝码跳出
c[abs(sumy - sumz)] = 1;//将能称出来的数据置1
sumy = 0;
sumz = 0;
return;
}
for (int k = 0; k < 3; k++)
{
b[u] = k;
for (int j = 0; j < n; j++)
{
if (b[j] == 1)sumy += a[j];
if (b[j] == 2)sumz += a[j];
}
dfs(u + 1);
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
sum += a[i];//算出最大的循换次数
}
dfs(0);
for (int i = 0; i < sum; i++)
{
if (c[i] == 1)ans++;//算所有能出来的重量
}
cout << ans;
return 0;
}
杨辉三角形
思路:应该要退公式,推不来,直接暴力骗分
#include<iostream>
using namespace std;
int a[1005][10005];
int b[100000005]; int t = 0;
void input()//将杨辉三角放到一个一维数组
{
for (int i = 0; i < 1000; i++)
{
a[i][0] = 1;
a[i][i] = 1;
}
for (int i = 2; i < 1000; i++)
for (int j = 1; j < i; j++)
{
a[i][j] = a[i - 1][j] + a[i - 1][j - 1];
}
}
int main()
{
int m;
cin >> m;
input();
for (int i = 0; i < 1000; i++)
for (int j = 0; j <= i; j++)
{
b[t++] = a[i][j];
}
for (int i = 0; i < t; i++)
{
if (b[i] == m) { cout << i + 1; break; }
}
return 0;
}
双向排序
#include <iostream>
#include <algorithm>
using namespace std;
int a[100005];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
a[i] = i + 1;
}
for (int i = 0; i < m; i++)
{
int p, q;
cin >> p >> q;
if (p == 1)
{
sort(a + q - 1, a + n);
}
if (p == 0)
{
sort(a, a + q, greater<int>());
}
}
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
return 0;
}
括号序列
思路:先算出左括号和右括号的差值,然后就知道要补什么符号,之后dfs,将每种的出来的括号序列存unordered_map,如果以前存过就不存这一种,我写的不能全对,望赐教
#include <iostream>
#include <unordered_map>
using namespace std;
string start;
unordered_map<string,int>mp;
int z = 0;
int y = 0;
int n = 0;
char ch;
int ans = 0;
bool is(string t)//判断是不是一个正确的括号序列
{
int temp = 0;
int fl = 0;
vector<bool>flag(t.length());//设一个数组存每一个括号,如果括号有对应的就把这个bool数组两个位置都射程true,如果最后所有都是true,那么就是一个正确的括号序列
for (int i = 0; i < t.length(); i++)
{
if (t[i] == '('&&flag[i]==false) {
int k = i;
fl = 0;
for (int j = k; j < t.length(); j++)
{
if (t[j] == ')'&&flag[j]==false) {
temp = j; fl = 1; break;
}
}
if(fl==1)
flag[k] = true;
flag[temp] = true;
}
}
for (int i = 0; i < t.length(); i++)
{
if (flag[i] == false)
{
return false;
}
}
return true;
}
void dfs(int u,string t)//层数为两种括号的差值
{
t = start;
if (u == n) {
if (mp.count(t) == 0 && is(t))ans++;
mp[t] = 1; return;
}
int len = start.length();
for (int i = 0; i < len; i++)
{
start.insert(i,1, ch);
dfs(u + 1, t);
start.erase(i, 1);
}
return;
}
int main()
{
cin >> start;
for (int i = 0; i < start.length(); i++)
{
if (start[i] == '(')z++;
if (start[i] == ')')y++;
}
n = abs(z - y);
if (z > y)ch = ')';
else
{
ch = ')';//判断要添加的是左括号还是右括号
}
dfs(0, start);
/*if (is("(("))cout << 123;*/
cout << ans%100000007;
}
最后一次更新于2021-04-30
123
By admin at December 16th, 2021 at 10:08 pm.
123
By admin at December 16th, 2021 at 10:06 pm.
123
By admin at December 16th, 2021 at 10:05 pm.
123
By admin at December 16th, 2021 at 10:05 pm.
123
By admin at December 16th, 2021 at 10:04 pm.
@admin
123
By admin at December 16th, 2021 at 10:06 pm.