马上要考2021第十二届的蓝桥杯,学校组织了模拟赛,用的是去年的国赛题。
做的真的垃圾,于是写一篇总结帖子。
A: 美丽的2 【水题 / 签到题】
答案: 563
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
#include<cmath>
using namespace std;
int main(void)
{
int sum=0;
for(int i=1;i<=2020;i++)
{
int temp=i;
while(temp)
{
int t=temp%10;
if(t==2)
{
sum++;
break;
}
temp/=10;
}
}
cout<<sum<<endl;
return 0;
}
B: 扩散 【爆搜】
20312088
就是爆搜,最早用的就是爆搜,但是就是出不来结果,最让我迷茫的是会不会数组越界的问题。
见了其它大佬们用来数组就解决了,问题是那个也没有啊,不知道原因。
#include<cstdio>
#include<string>
#include<iostream>
#include<queue>
using namespace std;
const int N=10010;
bool a[10005][10005];
bool map[10010][10010];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int ans;
struct node
{
int x,y,step;
}Node;
void bfs()
{
map[0][0]=true;
map[2020][11]=true;
map[11][14]=true;
map[2000][2000]=true;
queue<node>q;
Node.x=0; Node.y=0; Node.step=0;
q.push(Node);
Node.x=2020; Node.y=11; Node.step=0;
q.push(Node);
Node.x=11; Node.y=14; Node.step=0;
q.push(Node);
Node.x=2000; Node.y=2000; Node.step=0;
q.push(Node);
while(!q.empty())
{
node top=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int tempx=top.x+dx[i];
int tempy=top.y+dy[i];
int t=top.step+1;
if(map[tempx][tempy]==false&&t<=2020)
{
node m;
m.x=tempx;
m.y=tempy;
m.step=t;
map[tempx][tempy]=true;
q.push(m);
ans++;
}
}
}
}
int main(void)
{
bfs();
cout<<ans+4<<endl;//加上最开始的四个点
return 0;
}
见大佬,为了防止越界,统一加了很大的数,我觉得这种更容易懂。
#include<cstdio>
#include<string>
#include<iostream>
#include<queue>
using namespace std;
const int N=10010;
bool map[10010][10010];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int ans;
struct node
{
int x,y,step;
}Node;
void bfs()
{
map[0+3000][0+3000]=true;
map[2020+3000][11+3000]=true;
map[11+3000][14+3000]=true;
map[2000+3000][2000+3000]=true;
queue<node>q;
Node.x=0+3000; Node.y=0+3000; Node.step=0;
q.push(Node);
Node.x=2020+3000; Node.y=11+3000; Node.step=0;
q.push(Node);
Node.x=11+3000; Node.y=14+3000; Node.step=0;
q.push(Node);
Node.x=2000+3000; Node.y=2000+3000; Node.step=0;
q.push(Node);
while(!q.empty())
{
node top=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int tempx=top.x+dx[i];
int tempy=top.y+dy[i];
int t=top.step+1;
if(map[tempx][tempy]==false&&t<=2020)
{
node m;
m.x=tempx;
m.y=tempy;
m.step=t;
map[tempx][tempy]=true;
q.push(m);
ans++;
}
}
}
}
int main(void)
{
bfs();
cout<<ans+4<<endl;//加上最开始的四个点
return 0;
}
C: 阶乘约数 【数论】
答案: 39001250856960000
有公式的:
例: 6的约数有4个(1,2,3,6) 6=2*3 2的个数1 3的个数1 约数个数=(1+1)*(1+1)
8的约数有4个(1,2,4,8) 8=2*2*2 2的个数是3 约数个数=(3+1)*1=4
30的约数有(1,30,2,15,3,10,6,5) 30=2*3*5 2的个数是 1 3的个数是1 5的个数是1 约数个数=(1+1)*(1+1)*(1+1)=8;
总结: 一个数约数的个数等于这个数分解因子后,(每个质数的个数+1)的乘积
那么本问题就是 100!中约数的个数等于 (各个质数的个数+1)的乘积
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
#include<cmath>
using namespace std;
int a[25]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};//打质数表
int b[100];
long long int sum=1;
int main(void)
{
for(int i=2;i<=100;i++)
{
int temp=i;
for(int i=0;i<25;i++)
{
if(temp==1) break;
while(temp%a[i]==0)
{
b[a[i]]++;//统计各个质数的个数
temp/=a[i];
if(temp==1) break;
}
}
}
for(int i=2;i<=100;i++)
{
if(b[i])
{
sum*=(b[i]+1);各个质数的个数加1后的乘积
}
}
cout<<sum<<endl;
return 0;
}
转自: https://blog.csdn.net/ylwhxht/article/details/109694494
下面是大佬的思路。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<unordered_set>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define mp make_pair
#define pb push_back
#define G 6.67430*1e-11
#define rd read()
#define pi 3.1415926535
using namespace std;
const ll mod = 998244353;
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
ll gcd(ll a, ll b) { return !b ? a : gcd(b, a % b); }
int flag[105];
int main()
{
int i;
for (int i = 2; i <= 100; i++)
{
int tmp = i;
for (int j = 2; j <= tmp; j++)
{
while (tmp % j == 0)
{
tmp /= j;
flag[j]++;
}
}
}
ll ans = 1;
for (int i = 1; i <= 100; i++)
{
ans *= flag[i] + 1;
}
cout << ans;
}
E: 玩具蛇 【爆搜】
思路: 枚举每个蛇头的位置,爆搜。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
#include<cmath>
using namespace std;
int ans;
bool map[10][10];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
void dfs(int x,int y,int count)
{
if(x<0||x>=4||y<0||y>=4) return;
if(count==16)//可以放进去
{
ans++;
return;
}
for(int i=0;i<4;i++)
{
int tempx=x+dx[i];
int tempy=y+dy[i];
if(!map[tempx][tempy])
{
map[tempx][tempy]=true;
dfs(tempx,tempy,count+1);
map[tempx][tempy]=false;
}
}
}
int main(void)
{
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
memset(map,0,sizeof map);
map[i][j]=true;
dfs(i,j,1);
}
cout<<ans<<endl;
return 0;
}