A模拟

代码1

#include<bits/stdc++.h>
using namespace std; int n = 101;
int a[120][120];
int ans = 0; int main(){ //填充数组
int t = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
a[i][j] = ++t;
}
}
int cen = n/2+1;
int p = 1;
int l = 1,r=n;
//上半
for(int i=cen;i>=1;i--){
p = l;
while(p<=r){
ans += a[i][p];
p++;
}
l++;
r--;
}
l = 1,r = n;
p = 1;
cen = n/2+1+1;
l++;
r--;
//下半
for(int i=cen;i<=n;i++){
p = l;
while(p<=r){
ans += a[i][p];
p++;
}
l++;
r--;
}
cout<<ans<<endl;
return 0;
}

代码2

B-素数筛法打表+dfs全排列

思路

因为我们需要判断一个数字是否是素数判定次数过多,所以这里使用素数筛法打表,便于查询。

然后我们需要把这 8 个数字全排列,这里和之前的全排列不太一样,这里的全排列第一个数字不能是 0 ,另外我们还需要记录我们全排列的结果。所以我们使用一个数字来记录全排列的结果 num,这样也便于查询是否是素数 。添加一个数字的时候我们通过 10*num + i 完成把先添加的数字放到数字末尾 。

这些细节处理完之后,剩下的就是一个简单的递归了。答案是2668

代码1

#include<bits/stdc++.h>
using namespace std; typedef long long ll; int prime[100000005];
ll ans = 0; //素数筛打表
void Prime(){
for (int i = 2; i <= 100000005; i++) {
prime[i] = true;
}
for (int i = 1; i * i <= 100000005; i++) {
if (prime[i]) {
for (int j = i * i; j <= 100000005; j += i) {
prime[j] = false;
}
}
}
} int visited[10]; //全排列
void dfs(int x,int t){
if(x==8){
//判断是否是素数
if(prime[t]){
// cout<<t<<endl;
ans++;
}
return;
} for(int i=0;i<=7;i++){
if(i==0 && x==0){
continue;
}
if(!visited[i]){
visited[i] = 1;
dfs(x+1,t*10+i);
visited[i] = 0;
}
}
} int main(){
Prime();
memset(visited,0,sizeof(visited));
dfs(0,0);
cout<<ans<<endl;
return 0;
}

代码2

对于第一位数字不能为 0 ,我们可以通过判定 num 是否为 0 来判定第一位数字是否放 0 。



C-dfs搜索



思路1:手算

思路2:dfs

1、用 dfs 求解,每一次搜索,找到两个相同的边界点,标记即可。检测边界点的方法也很简单,只需要一个点的四个方向中有一个点在地图外或者已经被标记,那么这个点就是边界点。

2、检测边界点的方法也很简单,只需要一个点的四个方向中有一个点在地图外或者已经被标记,那么这个点就是边界点。答案是 89。

代码



D-快速幂



答案:pw(x, y / 2, p) * pw(x, y / 2, p) % p

E-末尾零的个数



答案:n = n / 5

对于一个数的阶乘(分解成多个素数相乘),如果想末尾出现 0 的话,只有当 5 和 2 出现的时候,才会在末尾出现 0 。

因为 2 的个数一定比 5 多。所以我们就可以得出一个结论,一个数的阶乘,末尾 0 的个数就是看里面 5 的个数。

现在变成求 1 到 n 的因子有多少个 5。对于包含 1 个 5 的数字,就是 n/5,包含两个 5 的数字个数为 n / 25。。。通过 n = n / 5 的方式,每次剥掉一层 5。

F-bfs+状态压缩







关于bfs+状态压缩:本题是典型的bfs + 状压,一个入口出口,还要拿到地图中多个东西,不知道每个东西拿的先后顺序,而且同一个点重复走的话不好标记,这时候就标记状态。

状态压缩:使用二进制标记状态

思路1

状态压缩 bfs,每个点状态用 d[x][y][state] 表示,state表示每个宝藏是否获取的状态压缩,比如(2<<10)-1 表示十进制的1023 也表示二进制的1111111111,即每个宝藏都拿到了。然后 bfs 即可。

思路2

全排列枚举选取宝藏的顺序,然后用 dfs 求出一个宝藏到另外一个宝藏之间的最短距离。优化的话,就是预处理任意两个宝藏之间的最短路距离。

思路3

手算得到答案48

思路4

1.全排列枚举到达各个宝藏的先后顺序

2.预处理最短距离,bfs算出两两宝藏之间(包括起点/终点)相互到达的最短距离, 并作记录存入ans数组

3.通过全排列枚举的顺序,通过ans数组计算最终距离,每次排列更新最短距离

代码1

ts = s | (1 << (mat[tx][ty] - '0'));//这句话意思就是更新状态(第mat[tx][ty]个宝藏找到了,所以要把它标记为1,怎么标记呢?与s作 | 运算把s的第mat[tx][ty]为置为1)



代码4

#include <i0stream>
#include <cstdi0>
#include <cstring>
#include <alg0rithm>
#include <queue>
#include <wind0ws.h>
using namespace std; /*
1.全排列枚举到达各个宝藏的先后顺序
2.预处理最短距离,bfs算出两两宝藏之间(包括起点/终点)相互到达的最短距离, 并作记录存入ans数组
3.通过全排列枚举的顺序,通过ans数组计算最终距离,每次排列更新最短距离
*/ b00l b00k[10][10];//标记地图上的是否访问过 int bz[11][2] = {0,7,1,6,2,4,3,1,3,8,4,4,6,8,7,6,8,1,9,6,0,0};//每个宝藏的坐标
int Map[10][10]= //整个地图 2表示不能走 1表示宝藏
{
{0,0,0,0,0,0,0,1,0,0},
{0,0,0,2,0,0,1,0,0,0},
{0,2,0,0,1,0,0,2,0,0},
{0,1,0,0,0,2,0,0,1,0},
{0,2,0,0,1,0,2,0,0,0},
{0,0,2,0,0,0,0,2,0,0},
{0,0,0,0,0,2,0,0,1,0},
{0,2,0,2,0,0,1,0,0,0},
{0,1,0,0,0,0,2,2,0,0},
{0,0,2,0,0,2,1,0,0,0}
};
struct n0de
{
int X,y,step;
} N0w,NeXt; int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; int bfs(int sX,int sy, int eX, int ey)
{
memset(b00k,0,size0f(b00k));
N0w.X = sX;
N0w.y = sy;
N0w.step = 0;
queue<n0de> q;
q.push(N0w);//起点入队
b00k[sX][sy] = true;
while(!q.empty())
{
N0w = q.fr0nt();
q.p0p();
//如果到了 当前理想要到的终点 就返回步数
if(N0w.X == eX && N0w.y == ey)
{
return N0w.step;
}
//搜寻4个方向入队
f0r(int i = 0; i < 4; i++)
{
NeXt.X = N0w.X + dir[i][0];
NeXt.y = N0w.y + dir[i][1];
NeXt.step = N0w.step + 1;
if(NeXt.X >= 0 && NeXt.X <= 9 && NeXt.y >= 0 && NeXt.y <= 9 && Map[NeXt.X][NeXt.y] != 2 && b00k[NeXt.X][NeXt.y] == false)
{
b00k[NeXt.X][NeXt.y] = true;
q.push(NeXt);
}
}
}
return -1;
}
int main()
{
int minn = 999999;
int ans[11][11];//记录宝藏到宝藏(包含起点,起点当作是10号宝藏)的最短路径 //枚举宝藏i 到 宝藏j的最短距离 121次bfs搜索
f0r(int i = 0; i < 11; i++)
{
f0r(int j = 0; j < 11; j++)
{
ans[i][j] = bfs(bz[i][0],bz[i][1],bz[j][0],bz[j][1]);
}
} int num[10] = {0,1,2,3,4,5,6,7,8,9};
d0
{
int sum = 0;
sum += ans[10][num[0]];//起点到第一个点的距离
f0r(int i = 0; i < 9; i++)
{
sum += ans[num[i]][num[i+1]];//宝藏到宝藏每一段路的距离
}
sum += ans[num[9]][10];//终点回到起点的距离
minn = min(minn,sum);//每次排列 更新最小值
}
while(neXt_permutati0n(num,num+10));//枚举10个宝藏到达顺序的全排列
c0ut << minn << endl;
return 0;
}

F-模拟,栈

思路

用栈来维护每次合并完的数,每入栈一个数以后栈顶和次栈顶比较,如果可以合并就合并为新的栈顶,并且再次与次栈顶比较直至无法合并,在合并过程中统计次数即可。

代码

#include<bits/stdc++.h>
using namespace std; stack<int> s;
int n;
int ans = 0; int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int d;
scanf("%d",&d);
while(!s.empty() && (s.top() - d) == 1){
s.pop();//大的数 去除
ans++;
}
if(!s.empty() && d - s.top() == 1){
ans++;
}else{
s.push(d);//小的数保留
}
}
printf("%d\n",ans);
return 0;
}

H:找规律

#include<bits/stdc++.h>
using namespace std; int n,m; int main(){
cin>>n>>m;
if(n > m){
swap(n,m);
}
//如果只有1行,那么在列上都放上棋子
if(n == 1){
cout<<m<<endl;
}else if(n == 2){
cout<< m / 4 * 4 + min(m%4,2) * 2<<endl;
}else{
cout<< (n * m + 1)/2<<endl;
}
return 0;
}

第一眼以为是dfs暴力搜索,过3组数据,超时了。

#include<bits/stdc++.h>
using namespace std; /*
从左到右、从上到下的顺序dfs搜索 每个格子都有两种可能:放、不放 dfs参数含义:横坐标、纵坐标、当前棋盘上已经放的个数
*/ typedef long long ll; int n,m,ans = 0;
int a[1010][1010];
int dr[8][2] = {{-1,-2},{-2,-1},{-2,1},{1,-2},{2,-1},{-1,2},{2,1},{1,2}}; bool in(int x,int y){
return x>=1 && x<=n && y>=1 && y<=m;
} int valid(int x,int y){
int flag = 1;
for(int i=0;i<=7;i++){
int dx = x + dr[i][0];
int dy = y + dr[i][1];
if(in(dx,dy) && (a[dx][dy] == 1)){
flag = 0;
break;
}
}
return flag;
} void dfs(int x,int y,int t){
if(x==n+1){
ans = max(ans,t);
return;
}
int dx = y>=m ? x+1 : x;
int dy = y>=m ? 1 : y+1; if(in(dx,dy) && a[dx][dy]!= 1 && valid(dx,dy)){
a[dx][dy] = 1;
dfs(dx,dy,t+1);
a[dx][dy] = 0;
}
dfs(dx,dy,t);
} int main(){
scanf("%d%d",&n,&m);
dfs(0,9,0);
printf("%d\n",ans);
return 0;
}

J-计数dp

思路1:dfs回溯+剪枝 过40%数据

#include<bits/stdc++.h>
using namespace std; typedef long long ll; int n,k,ans = 0; /*参数含义:第x个数(不多于k个数),当前剩余值t(初始为n),当前选的数num(小于n的自然数)*/
void dfs(int x,int t,int num){ //第x个数
if(t<0)return;
if(x>k+1)return;
if(x<=k+1){
if(t==0){
ans++;
return;
}
}
if(num>n)return;
//枚举选当前num的个数
for(int i=0;i<=(t/num+1);i++){
if(num*i <=t ){
dfs(x+i,t-num*i,num+1);
}
}
} int main(){
scanf("%d%d",&n,&k);
dfs(1,n,1);
printf("%d\n",ans);
return 0;
}

思路2:计数dp

可设dp[n][k]表示将正整数n分解为不多于k个正整数相加的形式的方案数。根据题意,应分以下4种情况讨论:

1°n=1 或 k=1:n=1时只有"1=1"这1种分解方案;k=1时只有"n=n"这1种分解方案,故方案数=1;

2°n<k:相当于dp[n][k],因正整数n不可能分解为超过n个正整数相加的形式;

3°n>k:根据"是否将n恰好分解为k个正整数相加的形式"(上界),进行讨论:

1°°将n恰好分解为k个正整数相加的形式:此时分解出的每个正整数t都满足t>=1,故相当于将分解出的k个数"都减去1",即相当于dp[n-k][k],也就是将正整数n-k分解为不多于k个正整数相加的形式的方案数;

2°°将n分解为小于k个正整数相加的形式:此时即dp[n][k-1],也就是将正整数n分解为不多于k-1个正整数相加的形式的方案数;

故方案数=dp[n-k][k]+dp[n][k-1];

4°n=k:总体与3°相同,但将n恰好分解为k个正整数相加的形式时,只有"n=n/k+n/k+...+n/k"这1种分解方案,故方案数=1+dp[n][k-1]。

综上,可得以下结论:

#include<bits/stdc++.h>
using namespace std; typedef long long ll;
int n,k;
ll dp[310][310]; int main(){
cin>>n>>k;
for(int i = 1;i<=n;i++){
for(int j=1;j<=k;j++){
//等于1的时候
if(i==1 || k == 1){
dp[i][j] = 1;
}else if(j > i){
dp[i][j] = dp[i][i];
}else if(i > j){
dp[i][j] = dp[i][j-1] + dp[i-j][j];
}else{
dp[i][j] = dp[i][j-1] + 1;
}
}
}
cout<<dp[n][k]<<endl;
return 0;
}

2018 蓝桥杯省赛 B 组模拟赛(五)的更多相关文章

  1. 52-2018 蓝桥杯省赛 B 组模拟赛(一)java

    最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增.比如 212212 就是一个U型数字,但是 333333, 9898, 567567, 313133131 ...

  2. 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

    2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...

  3. 2015年第六届蓝桥杯C/C++B组省赛题目解析

    一.奖券数目 有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利.虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求.某抽奖活动的奖券号码是5位数(10000-99999),要求其中 ...

  4. 计蒜客2018 蓝桥杯省赛 B 组模拟赛(一)

    1,结果填空:年龄 今天蒜头君带着花椰妹和朋友们一起聚会,当朋友们问起年龄的时候,蒜头君打了一个哑谜(毕竟年龄是女孩子的隐私)说:“我的年龄是花椰妹年龄个位数和十位数之和的二倍”. 花椰妹看大家一脸懵 ...

  5. 【2018.10.18】noip模拟赛Day2 地球危机(2018年第九届蓝桥杯C/C++A组省赛 三体攻击)

    题目描述 三体人将对地球发起攻击.为了抵御攻击,地球人派出了 $A × B × C$ 艘战舰,在太 空中排成一个 $A$ 层 $B$ 行 $C$ 列的立方体.其中,第 $i$ 层第 $j$ 行第 $k ...

  6. 2018 蓝桥杯省赛 B 组模拟赛

    C. 结果填空:U型数字 最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增.比如 212 就是一个U型数字,但是 333, 98, 567, 3131,就是 ...

  7. 2019 蓝桥杯省赛 A 组模拟赛(一)-忽明忽暗

    走廊里有 nn 盏灯,编号依次为 1,2,3,...,n,由学校电路控制中心管理.初始时,所有灯都是关闭的.某黑客入侵了学校电路控制中心,黑客想让灯忽明忽暗,进行了 n 轮操作.第 i 轮操作,会让所 ...

  8. 2019 蓝桥杯省赛 A 组模拟赛(一)-修建公路

    题目: 蒜头国有 nn 座城市,编号分别为 0,1,2,3,...,n-1.编号为 x 和 y 的两座城市之间如果要修高速公路,必须花费 x|y 个金币,其中|表示二进制按位或. 吝啬的国王想要花最少 ...

  9. 计蒜客 2019 蓝桥杯省赛 B 组模拟赛(三)一笔画

    #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> us ...

随机推荐

  1. tfs团队项目删除原来连接的默认账户

    1.在用visual studio 连接团队项目时,首次输入用户名和密码后,默认保存住凭据了,等以后连接会自动采用首次的凭证. 但是如何采用新的用户重新登录呢.如图所示,删除原有的凭证.删除后重启电脑 ...

  2. Lua之math

    Lua之math函数: 转载请注明出处:http://www.cnblogs.com/jietian331/p/8032555.html abs 取绝对值 math.abs(-15) 15 acos ...

  3. Core Java Fundation

    http://www.cnblogs.com/cmfwm/p/7671188.html http://blog.csdn.net/fuckluy/article/details/50614983 ht ...

  4. django后台将最新文章显示在前面

    在你定义的views.py中修改 Models.objects.order_by("-pub_date")    更据时间排列 Models.objects.order_by(&q ...

  5. Rpgmakermv(34) Mog_Event Sensor

    原文: =============================================================================+++ MOG - Event Sen ...

  6. Real Time Credit Card Fraud Detection with Apache Spark and Event Streaming

    https://mapr.com/blog/real-time-credit-card-fraud-detection-apache-spark-and-event-streaming/ Editor ...

  7. scu 4439 Vertex Cover

    题意: 给出n个点,m条边,将若干个点染色,使得每个边至少有一点染色,问至少染多少个点. 思路: 如果是二分图,那就是最小点覆盖,但是这是一般图. 一般图的最小覆盖是npc问题,但是这题有一个条件比较 ...

  8. NSOperation、NSOperationQueue(II)

    NSOperationQueue 控制串行执行.并发执行 NSOperationQueue 创建的自定义队列同时具有串行.并发功能 这里有个关键属性 maxConcurrentOperationCou ...

  9. Spark学习之路 (二十三)SparkStreaming的官方文档

    一.SparkCore.SparkSQL和SparkStreaming的类似之处 二.SparkStreaming的运行流程 2.1 图解说明 2.2 文字解说 1.我们在集群中的其中一台机器上提交我 ...

  10. tomcat 、NIO、netty 本质

    tomcat 基于 Socket,面向 web 浏览器的通信容器 nio 同步非阻塞的I/O模型 netty 通信框架,对 nio 的封装