填空题
有一说一,今年没只有两个没想到
T1 题A: 九进制转十进制
感觉没啥好说的,逢9进1。
1478 // should 1458 + 18 + 2 = 1,478
T2 题B: 顺子日期
蓝桥杯歧义,建议冲锋
4
大题
我犯了很多错误,已自裁
T1 题C: 刷题统计
送分题,不多说,不开ULL,见祖宗。
#include "iostream"
using namespace std;
#define ULL unsigned long long
ULL a, b, n;
int main()
{
cin >> a >> b >> n;
ULL week = 0;
week = a * 5 + b * 2;
ULL week_cnt = n / week;
n = n % week;
ULL day = 0;
while (n > 0)
{
if (day < 5)
{
n -= a;
day++;
}
else
{
n -= b;
day++;
}
}
day += week_cnt * 7;
cout << day;
return 0;
}
T2 题D: 修剪灌木
找规律,不会的话可以像我一样,多写点数据,就出来了
#include "iostream"
using namespace std;
#define ULL unsigned long long
ULL tree[10001] = {};
ULL n;
int main()
{
cin >> n;
ULL index = n;
if ((index % 2) == 1)
index = index / 2 + 1;
else
{
index = index / 2;
}
for (int i = 1; i <= index; i++)
{
tree[i] = (n - i) * 2;
}
for (int i = 1; i <= index; i++)
{
cout << tree[i] << endl;
}
if ((n % 2) == 1)
index--;
for (int i = index; i > 0; i--)
{
cout << tree[i] << endl;
}
return 0;
}
T3 题E: X 进制减法
看样例,主要是要理解,我手写了120 对应11 5 2 进制的数,就稍微理解了。
求出值一减就行。
#include "iostream"
#define FOREACH(a, b) for (int a = 0; i < b; a++)
#define ULL unsigned long long
using namespace std;
int N = 0;
int aLen = 0;
int a[1001] = {};
int bLen = 0;
int b[1001] = {};
int base[1001] = {};
ULL an;
ULL bn;
int main()
{
//freopen("in.txt", "r+", stdin);
cin >> N;
cin >> aLen;
for (int i = 0; i < aLen; i++)
{
cin >> a[i];
}
cin >> bLen;
for (int i = 0; i < bLen; i++)
{
cin >> b[i];
}
//找进制
for (int i = 0; i < aLen; i++)
{
if (a[i] > b[i])
{
if (a[i] == 0 || a[i] == 1)
base[i] = 2;
else
base[i] = a[i] + 1;
}
else
{
if (b[i] == 0 || b[i] == 1)
base[i] = 2;
else
base[i] = b[i] + 1;
}
}
int max = 0, max_index = 0;
for (int i = 0; i < aLen; i++)
{
if (a[i] > max)
{
max = a[i];
max_index = i;
}
if (b[i] > max)
{
max = b[i];
max_index = i;
}
}
base[max_index] = N;
//计算值
ULL jin = 1;
for (int i = aLen - 1; i >= 0; i--)
{
if (i - (aLen - 1) == 0)
an += a[i];
else if (i - (aLen - 1) == 1)
{
jin *= base[i + 1];
an += a[i] * base[i + 1];
}
else
{
jin *= base[i + 1];
an += (a[i] * jin) % 1000000007;
}
}
// cout << an << endl;
jin = 1;
for (int i = bLen - 1; i >= 0; i--)
{
if (i - (bLen - 1) == 0)
bn += b[i];
else if (i - (bLen - 1) == 1)
{
jin *= base[i + 1];
bn += b[i] * base[i + 1];
}
else
{
jin *= base[i + 1];
bn += (b[i] * jin) % 1000000007;
}
}
// cout << bn << endl;
cout << (an - bn) % 1000000007 << endl;
return 0;
}
T4 题F: 统计子矩阵
摆烂没写(实际上是时间不够了),四重for循环也能写出来,但是感觉不是正解。
理论上可以前缀和优化?蓝桥杯必出前缀和来着。
#include "iostream"
#define ULL unsigned long long
using namespace std;
int x, y, N;
int arr[501][501] = {};
ULL cnt = 0;
int main()
{
cin >> x;
cin >> y;
cin >> N;
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
{
cin >> arr[y][x];
if(arr[y][x] <= N)
cnt++;
}
// 四重for暴力找
return 0;
}
T5 题G: 积木画
不会,想着可能是DP,找规律恶心我了,写出2*4知道大概有11个?就没写,严格来说就写了读入。
按理来说应该是有规律的,2 5 11。
大佬说是二重前缀和,和大佬贴贴(lianyi超强的,他在友链里面,快去看看
T6 题H: 扫雷
有点长hhh,现场学的map。
爆搜挂着机,可能出现在找圆的时候TIME OUT,我人应该是魔怔了,应该读入的时候做优化的
也就是说。。。优化了炸弹爆炸,应该就可以AC,应该还是遍历MAP树的方式,或者说队列,我是xxx
#include "iostream"
#include "vector"
#include "map"
#define ULL unsigned long long
using namespace std;
int n, m;
typedef struct node
{
/* data */
ULL x, y;
ULL range;
};
map<pair<ULL, ULL>, int> BOOM_map;
map<pair<ULL, ULL>, int> FIRE_map;
node boom[50000];
node fire[50000];
ULL cnt;
//检查是不是炸弹
inline bool cheak(int x, int y)
{
auto res = BOOM_map.find(pair<ULL, ULL>(x, y));
if (res == BOOM_map.end())
return false;
else
return true;
}
//以圆圈方式查找炸弹,已经炸的-1
void dfs(int x, int y, int range)
{
int i = 0, j = 0;
while (1)
{
if (i * i + j * j <= range * range)
{
if (cheak(i, j))
{
//开炸 dfs寻找
int range_n = BOOM_map.at(pair<ULL, ULL>(i + x, j + y));
if (range_n != -1)
{
cnt++;
BOOM_map.at(pair<ULL, ULL>(i + x, j + y)) = -1;
dfs(i, j, range_n);
}
}
if (cheak(-i, j))
{
int range_n = BOOM_map.at(pair<ULL, ULL>(-i + x, j + y));
if (range_n != -1)
{
cnt++;
BOOM_map.at(pair<ULL, ULL>(-i + x, j + y)) = -1;
dfs(-i, j, range_n);
}
}
if (cheak(i, -j))
{
int range_n = BOOM_map.at(pair<ULL, ULL>(i + x, -j + y));
if (range_n != -1)
{
cnt++;
BOOM_map.at(pair<ULL, ULL>(i + x, -j + y)) = -1;
dfs(i, -j, range_n);
}
}
if (cheak(-i, -j))
{
int range_n = BOOM_map.at(pair<ULL, ULL>(-i + x, -j + y));
if (range_n != -1)
{
cnt++;
BOOM_map.at(pair<ULL, ULL>(-i + x, -j + y)) = -1;
dfs(-i, -j, range_n);
}
}
i++;
j++;
}
else
break;
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> boom[i].x >> boom[i].y >> boom[i].range;
BOOM_map.insert(pair<pair<ULL, ULL>, int>(pair<ULL, ULL>(boom[i].x, boom[i].y), boom[i].range));
}
for (int i = 0; i < m; i++)
{
cin >> fire[i].x >> fire[i].y >> fire[i].range;
FIRE_map.insert(pair<pair<ULL, ULL>,int>(pair<ULL, ULL>(fire[i].x, fire[i].y), fire[i].range));
}
// 遍历火箭map
for (auto iter : FIRE_map)
{
int x = iter.first.first;
int y = iter.first.second;
int range = iter.second;
dfs(x, y, range);
}
cout << cnt;
return 0;
}
T7 题 I: 李白打酒加强版
最后10分钟,没写完,就这样吧,退出有问题,别看了,放着凑字数
#include "iostream"
#define ULL unsigned long long
using namespace std;
ULL N, M; // double sub1
ULL cnt;
ULL jiu = 0;
void dfs()
{
if (N == 0 && M == 0)
{
cnt++;
cnt %= 1000000007;
return;
}
if (N < 0 || jiu < 0 || M < 0)
return;
N = N - 1;
jiu *= 2;
dfs();
N++;
jiu /= 2;
M--;
jiu--;
dfs();
jiu++;
M++;
}
int main()
{
cin >> N >> M;
dfs();
cout << cnt;
return 0;
}
T8 题J: 砍竹子
有思路,没时间,后面补了注释,就这样吧,有点暴力,但我觉得是对的。
STL不够熟,哈希模板不备,就是这个下场
#include "iostream"
#include "map"
#include "cmath"
#include "vector"
#define ULL unsigned long long
using namespace std;
map<ULL, int> arr; // 高度 数量
unsigned int num;
ULL cntMAX;
void dfs(ULL cnt)
{
// 如果都为 0 跳出循环
// 根据cnt 剪枝
for (auto iter = arr.rbegin(); iter != arr.rend(); iter++)// 问题在于,迭代器失效 似乎砍之后会给有效的迭代器
{
// 逆序读取高度 这样才是最高的
// 砍第一个
// 没砍到比第二个小的?继续砍
// dfs
// 还原第一个
}
}
int main()
{
cin >> num;
for (int i = 0; i < num; i++)
{
ULL high;
cin >> high;
if (arr.find(high) == arr.end())
arr.insert(pair<ULL, int>(high, (int)1));
else
arr.at(high)++;
}
dfs(0);
cout << cntMAX;
return 0;
}