2021蓝桥杯A组
没啥说的枚举
这里用到stl里面的set 来保存每条直线的斜率和截距
点击查看代码
#include<bits/stdc++.h>
using namespace std;
struct point{
int x; //横坐标
int y; //纵坐标
};
int main(){
vector<point> p; //存放所有点
for(int i=0; i<20; i++)
for(int j=0; j<21; j++)
p.push_back({i,j});
int len = p.size();
set<pair<double, double> > lines; //存放直线的斜率与截距
for(int i=0; i<len; i++){
for(int j=0; j<len; j++){
if (p[i].x != p[j].x && p[i].y != p[j].y){ //统计所有斜直线的情况
double k = (p[j].y - p[i].y) * 1.0 / (p[j].x - p[i].x);
double b = (p[j].y * (p[j].x - p[i].x) - (p[j].y - p[i].y) * p[j].x) * 1.0 / (p[j].x - p[i].x);
lines.insert(pair<double, double>(k,b));
}
}
}
cout << lines.size() + 20 + 21 << endl; //总线=斜线+横直线+竖直线
return 0;
}
这个题稍微有些难度
如果题目还要复杂点 不能用计数的方法计算 就要用搜索dfs了
可以跑最短路 也可以线性转移 如果数据大一点就只能线性转移了
点击查看代码
#include<bits/stdc++.h>
#define MAX 999999999
int path[2100] = {0};
using namespace std;
//两点之间的路径
long long gcd(int a, int b) {
if (a % b == 0)
return b;
return gcd(b, a % b);
}
long long lcm(int a, int b) {
return a * b / gcd(a, b);
}
int main(){
memset(path, 0, sizeof(path));
for(int i=2; i<=2021; i++)
path[i] = MAX;
for(int i=1; i<=2021; i++){
for(int j=i+1; j<=i+21; j++){
long long edge = lcm(i,j);
if(path[j] > path[i] + edge)
path[j] = path[i] + edge;
}
}
cout << path[2021] << endl;
return 0;
}
这个题爆搜可能是不行的 考虑状压dp
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
bool v[25][25];
ll dp[1<<21][25];
inline int gcd(int a, int b){
return b==0 ? a : gcd(b, a%b);
}
int main(void)
{
ll res = 0;
for(int i = 1;i <= 21; i++){
for(int j = 1; j <= 21; j++){
if(gcd(i, j) == 1)
v[i-1][j-1] = v[j-1][i-1] = true;
else
v[i-1][j-1] = v[j-1][i-1] = false;
}
}
dp[1][0] = 1;
for(int i = 1; i < (1<<21); i++){
for(int j = 0; j < 21; j++){
if(!(i>>j&1)) continue;
for(int k = 0; k < 21; k++){
if((i>>k&1) || !v[j][k]) continue;
dp[i+(1<<k)][k] += dp[i][j];
}
}
}
for(int i = 0; i < 21; i++)
res += dp[(1<<21)-1][i];
cout <<res;
return 0;
}
如果砝码只能放一边就是一个01背包,但是现在条件是可以放两边 怎么办?
其实就是在原基础上的01背包上加以改进
原先是for(int j=max;j>val[i];j--)
改成 for(int j=max;j>-val[i];j--)
注意数组下标不能为负 所以要整体加一个大整数
还考博弈论 蓝桥杯还是有点难度嘛
这题题目初始a,b都为0,没有表示清楚
首先是很容易想到最高位1的个数的,因为只要谁霸占了最高位的1,不管后面几位怎么弄都是大不过他的
考虑最高位是偶数 那不分上下 肯定是每人占俩 特别的如果每个位置上1的个数都是偶数 那么就是平局 也就是数列异或和等于0
考虑最高位是奇数 那一定有 一个人是偶数个1,一个人是奇数个1,这样奇数个1肯定是胜出 但是还有0要分配啊
分配0同样分为奇偶两种情况
奇数个0,相当于先后手互换 ;
偶数个0,先手还是先手,后手还是后手;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具