1.平方和
思路:求出这样的数字,直接平方和;包含这样的数,只需对每一位数字进行检查,不断地取余,判断,再除10,对下一位数字取余,除完了循环终止;
代码:
#include<iostream>
using namespace std;
int main() {
int n = 2019;
int m;
long long sum = 0;
for (int i = 1; i <= n; i++)
{
int k = i;
while (k) {
m = k % 10;
if (m==0||m == 2 || m == 1 || m == 9) {
sum += i * i;
break;
}
k /= 10;
}
}
cout << sum;
}
1.2立方和
#include<iostream>
using namespace std;
typedef long long ll;
int main() {
ll a,sum=0;
for (int i = 1; i <= 2019; i++) {
a = i;
while (a) {
if (a % 10 == 0 || a % 10 == 2 || a % 10 == 1 || a % 10 == 9) {
sum += i*i*i;
//cout << i << endl;
break;
}
a = a / 10;
}
}
cout<<sum<<endl;
}
2.数列求值
思路:最开始想到用数组直接求,递归或者迭代的思想,但是提示存放数组字节超出。由于题目仅仅需要输出后四位,加法只需要只计算后四位就行,因此可以只保留每一次计算的后四位数字。
注意:
大数组定义在main函数中?
数组定义在函数中时,占用的内存来自栈空间,栈空间是在进程创建时初始化的,有固定的大小,一般为几十KB,所以在main函数内部定义大数组相当于在栈内需要一个很大的空间,会造成栈的溢出。全局变量在静态存储区内分配内存,而局部变量是在栈内分配内存空间的。 因此,当我们需要定义一个极大的数组时,最好在main函数外部定义这个大数组。
代码如下:
#include<iostream>
using namespace std;
typedef long long ll;
const ll N = 20190324;
int a[N] = { 0 };
int main() {
a[1] = a[2] = a[3] = 1;
ll n=20190324;
for (int i = 4; i <=n; i++) {
a[i] = (a[i - 1] + a[i - 2] + a[i - 3])%10000;
}
cout << a[n];
}
3.字串数字
进制转化
#include<iostream>
using namespace std;
#include<string>
typedef long long ll;
int main() {
string s;
ll sum=0;
cin >> s;
for (int i = 0; i < size(s); i++)
{
sum = sum*26+s[i] - 'A' + 1;
}
cout << sum;
}
4.最大降雨量
/* * [][][][a][][][]
* [][][][b][][][]
* [][][][c][][][]
* [][][][max][][][]
* [][][][d][][][]
* [][][][e][][][]
* [][][][f][][][] * *
此题意思为将1至49分为7组数字,求取七组数字中每组数字的中位数所构成的数列的中位数的最大值 * 即如图所示,最大化[max] * 49个数字中需要比[max]大的有[max]行的后三位,d、e、f行的后四位,共3+3*4=15位 * 结果为:49-15=34
5.质数
直接暴力:
#include<iostream>
using namespace std;
#include<math.h>
typedef long long ll;
int main() {
ll sum=0,res=1;
for (int i = 2; sum != 2019; i++) {
int j = 2;
for (; j <= sqrt(i); j++) {
if (i % j == 0)
break;
}
if (j > sqrt(i)) {
sum++;
}
res = i;
}
cout << res;
}
6.迷宫
思路:
本题使用宽度优先搜索,主要核心是两个部分:
1.进行更新各点到终点的最短距离,这部分主要在于检查部分:除了边界点,障碍物点,未访问点,其中未访问点是以未更新最短距离为条件。其中计算最短距离是以终点为起点进行计算。
2.主函数部分,进行一次最短距离计算,从起点开始算,判断条件除了边界点,障碍物点,如果最短距离符合则为下一步该走的点。
代码:
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <queue>
using namespace std;
char a[40][60]; //存图
int nextx[4] = { 1,0,0,-1 }, nexty[4] = { 0,-1,1,0 }; //D<L<R<U 方向数组按照字典序的顺序走 UD为x方向,LR为y方向
int dist[40][60]; //定义一个dist数组,用来存放各点到终点的最短距离
char dir[4] = { 'D','L','R','U' };
bool check(int x, int y) { //判断边界以及是否访问
return x > 0 && y > 0 && x <= 30 && y <= 50 && a[x][y] == '0' && dist[x][y] == -1;
}
void bfs() { //BFS扫一遍,求出各点到终点的最短距离
queue<pair<int, int>>q;
memset(dist, -1, sizeof(dist)); //将dist数组中的所有字节的值设置为-1,用来标记未访问元素
dist[30][50] = 0; //终点到终点距离为0,用来设置终止条件
q.push({ 30,50 });
while (!q.empty()) { //bfs运算
pair<int, int> t = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int newx = t.first + nextx[i]; //按照定好的方向数组运算
int newy = t.second + nexty[i];
if (check(newx, newy)) { //计算距离
dist[newx][newy] = dist[t.first][t.second] + 1;
q.push({ newx,newy }); //按宽度入队
}
}
}
}
int main() {
for (int i = 1; i <= 30; i++)
for (int j = 1; j <= 50; j++)
{
cin >> a[i][j];
}
bfs(); //调用一次bfs,计算出各点距离终点距离
int x = 1, y = 1; //从起点开始遍历
string res; //存答案
while (x != 30 || y != 50) { //只要不到终点便一直运行
for (int i = 0; i < 4; i++) {
int newx = x + nextx[i];
int newy = y + nexty[i];
if (newx > 0 && newy > 0 && newx <= 30 && newy <= 50 && a[newx][newy] == '0' && dist[newx][newy] == dist[x][y] - 1) {
x = newx, y = newy;
res += dir[i];
break;
}
}
}
cout << res << "\n";
return 0;
}
7.蛇形填数
把对角线的摘出来,1,5,13,25.......
看规律,第一行第一列是1,第二行第二列实际是 1+2+3-[3/2],第三行第三列是 1+2+3+4+5-[5/2]
第四行第四列就是 1+2+3+4+5+6+7-[7/2];
规律为 第n行第n列就是 1+2+....+(2n-1)-[(2n-1)/2];
8.成绩分析
注意输出的时候 sum/n 将其强转成float就能保留小数位,printf("%.2f",(float)sum/n);就能保留两位小数
9.回文日期
暴力就行,注意添加检查条件:月份和日期的合法性,闰年二月合法性,大小月的合法性;
代码:
#include<iostream>
using namespace std;
int year, month, day;
int a[8];
bool check(int _year,int _month,int _day) { //检查八位数日期合不合法
if (_month == 2) {//闰年二月
if ((_year % 4 == 0 && _year % 100 != 0) || (_year % 400 == 0)) {
if (_day > 29)
return false;
}
else {
if (_day > 28)
return false;
}
}
if (_month > 12||_month==0 || _day > 31||_day==0) //月,日
return false;
if (_month == 4 || _month == 6 || _month == 9 || _month == 11) { //大小月
if (_day > 30)
return false;
}
return true;
}
void func(int N) {
a[0] = N % 10;
a[1] = (N / 10) % 10;
a[2] = (N / 100) % 10;
a[3] = (N / 1000) % 10;
a[4] = (N / 10000) % 10;
a[5] = (N / 100000) % 10;
a[6] = (N / 1000000) % 10;
a[7] = (N / 10000000) % 10;
year = (N / 10000);
month = (N / 100) % 100;
day = N % 100;
}
int main() {
int N; //输入的八位数字
cin >> N;
bool tiao=false;
for (int i = N+1; i < 99999999; i++) {
//回文数
func(i);
if (a[0] == a[7] && a[1] == a[6] && a[2] == a[5] && a[3] == a[4] && !tiao) {
if (check(year, month, day)) {
cout << i << endl;
tiao = true;
}
}
if (a[0] == a[7] && a[1] == a[6] && a[2] == a[5] && a[3] == a[4]&& a[0] == a[2] && a[1] == a[3])
if (check(year, month, day)) {
cout << i << endl;
break;
}
}
return 0;
}
10.作物杂交
参考【蓝桥杯2020省赛】【深度优先搜索】作物杂交(详解!)-CSDN博客
代码如下:主要是利用递归解决,感觉挺像动态规划的方法。另外还学到了可以自定义一个结构体,再利用一个二维数组来存储所有的能得到该作物的杂交办法。不断地迭代来求能得到该作物的时间和父母作物的时间来求。
#include <iostream>
#include <algorithm>
#include "string.h"
#include <vector>
using namespace std;
struct parent //存储杂交方案
{
int x;
int y;
};
int n, m, k, t, tmp;
long long plant_time[2005];//每种作物的种植时间
bool flag[2005];//标记是否出现了该作物
long long min_hybrid_time[2005];//杂交出每种作物的最短时间
vector< vector<parent> >hybrid(2005);//存储每种作物的所有杂交方案
long long solve(int now)
{
if (flag[now])//若是已有杂交出该种作物的最短时间
return min_hybrid_time[now];//直接返回即可
for (int i = 0; i < hybrid[now].size(); i++)//对能够杂交出当前作物的方案都尝试一下
{
parent tmp = hybrid[now][i];//能够杂交出当前作物的第i种方案
//当前作物的最短杂交时间是 杂交出该作物的所有方案 中的最短时间
//而每种方案的最短时间是种植其‘父母’作物所需要的时间 + 其父母作物杂交所需的的最短时间(=两者杂交所需时间中的最大值)
min_hybrid_time[now] = min(min_hybrid_time[now], max(plant_time[tmp.x], plant_time[tmp.y]) + max(solve(tmp.x), solve(tmp.y)));
}
flag[now] = true;//标记已经找到最短杂交时间
return min_hybrid_time[now];//返回最短杂交时间
}
int main()
{
cin >> n >> m >> k >> t;
memset(min_hybrid_time, 0x3f, sizeof(min_hybrid_time));//杂交出每种作物的最短时间初始化为最大值
memset(flag, false, sizeof(flag));//作物标记初始化
//注意作物的下标从1开始!!!
for (int i = 1; i <= n; i++)//输入种植时间
cin >> plant_time[i];
for (int i = 0; i < m; i++)//输入初始种子数据
{
cin >> tmp;
flag[tmp] = true;//标记已经有了最短杂交时间
min_hybrid_time[tmp] = 0;//最短杂交时间 = 0,因为不需要杂交
}
for (int i = 0; i < k; i++)//输入所有杂交方案
{
parent temp;
cin >> temp.x >> temp.y >> tmp;
hybrid[tmp].push_back(temp);//存储杂交方案
}
solve(t);//递归求解
cout << min_hybrid_time[t] << endl;//输出杂交出目标作物的最短时间
return 0;
}
11.最短路
迪杰斯特拉
#include <iostream>
#include <cstring>
using namespace std;
const int N = 200, n = 19;
int dist[N]; //存储最短路的距离
int g[N][N]; //权值
void add(char x, char y, int c) //制作图的权值
{
int a = x - 'A' + 1; //用ASKII码来实现对顶点进行排序
int b = y - 'A' + 1;
g[a][b] = g[b][a] = c; //赋权
}
bool vis[N]; //标记顶点是否处理过
int dijkstra() //迪杰斯特拉算法
{
memset(dist, 0x3f, sizeof dist); //将顶点全部初始化为无穷大
dist[1] = 0; //初始化,从A到A的最短距离为0
for (int i = 0; i < n; i++)
{
int t = -1; //用于存放未访问的节点中距离起点最近的顶点的编号
for (int j = 1; j <= n; j++)
{
if (!vis[j] && (t == -1 || dist[j] < dist[t])) //如果未处理,且 顶点紧邻起点或者
t = j;
}
vis[t] = 1; //标记已经处理完的顶点
for (int j = 1; j <= n; j++)
{
dist[j] = min(dist[j], dist[t] + g[t][j]); //更新最短路距离
}
}
return dist[n];
}
int main()
{
memset(g, 0x3f, sizeof g);
add('A', 'B', 2);
add('A', 'C', 1);
add('A', 'D', 1);
add('A', 'D', 1);
add('B', 'J', 2);
add('B', 'G', 1);
add('C', 'D', 3);
add('C', 'F', 3);
add('C', 'G', 3);
add('D', 'E', 1);
add('D', 'G', 2);
add('D', 'H', 1);
add('D', 'I', 2);
add('E', 'H', 1);
add('E', 'I', 3);
add('F', 'G', 1);
add('F', 'J', 1);
add('G', 'F', 1);
add('G', 'I', 3);
add('G', 'K', 2);
add('H', 'I', 1);
add('H', 'L', 2);
add('I', 'M', 3);
add('J', 'S', 2);
add('K', 'N', 1);
add('K', 'L', 3);
add('K', 'P', 2);
add('L', 'M', 1);
add('L', 'R', 1);
add('M', 'N', 2);
add('M', 'Q', 1);
add('M', 'S', 1);
add('N', 'P', 1);
add('O', 'P', 1);
add('O', 'Q', 1);
add('O', 'R', 3);
add('R', 'S', 1);
cout << dijkstra();
return 0;
}
12.约数个数
#include<bits/stdc++.h>
using namespace std;
int main(){
int n=78120;
int sum=0;
for(int i=1;i*i<n;i++){
if(n%i==0){
sum++;
}
}
cout<<2*sum;
}
13.寻找2020
#include<iostream>
#include<string>
using namespace std;
char a[300][300];
int ant = 0;
void find1(int i, int j)
{
if (a[i][j] != '2')
return;
//向右
if (j + 3 < 300)
{
if ((a[i][j + 1] == '0') && (a[i][j + 2] == '2') && (a[i][j + 3] == '0'))
ant++;
}
if (i + 3 < 300)
{
if ((a[i + 1][j] == '0') && (a[i + 2][j] == '2') && (a[i + 3][j] == '0'))
ant++;
}
if ((j + 3 < 300) && (i + 3 < 300))
{
if ((a[i + 1][j + 1] == '0') && (a[i + 2][j + 2] == '2') && (a[i + 3][j + 3] == '0'))
ant++;
}
return;
}
int main()
{
for (int i = 0; i < 300; i++)
for (int j = 0; j < 300; j++)
cin >> a[i][j];
for (int i = 0; i < 300; i++)
for (int j = 0; j < 300; j++)
find1(i, j);
//cout << ant << endl;
cout<<16520<<endl;
return 0;
}