那么,作为一名初入信息竞赛的选手,我也试着开始用博客记录自己的学习历程,那么这篇文章先简单介绍一下我自己吧。

本人开始学习信息学大概以来,主要都是用的C++,所以对其他语言并不是十分熟悉。2016我还只是一名NOIP普及组的选手,水掉一个一等奖后美滋滋继续往下学。最近刚刚搞完今年HDNIOIP提高组前,听同学说最后一道题是省选第二题的难度后我懵逼了(由于最近刚比完如果想要题解可以搜索“xjr01”, hdNOIP2017 题解 -> " http://www.cnblogs.com/xiao-ju-ruo-xjr/ "),其实第一篇文章也不知道写什么,那就胡乱写一下普及组的题解吧(无聊)。

那么首先来看第一题

无脑暴力,哈希前缀和什么的随便写,就不解释了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 2020
using namespace std;
int n,m,k,a[M],ans,x,y,tmp;
int need(int x){if(x%k==0) return x/k;return x/k+1;
}
int main(){scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);a[x]++;a[y]--;}for(int i=1;i<=n+1;i++){tmp+=a[i];ans=max(ans,need(tmp));}ans=min(ans,need(m));printf("%d",ans);return 0;
}

第二题,一个简单的动态规划

设 f [ i ][ j ][ 0 ]表示时刻 i 时耗费了 j 的体力来到a树,f [ i ][ j ][ 1 ]表示时刻 i 时耗费了 j 的体力来到b树。

转移:

f [ i ][ j ][ 1 ]可以从 f [ i-1 ][  j-2 ][ 0 ]和 f [ i-1 ][ j ][ 1 ]转移

f [ i ][ j ][ 0 ]可以从 f [ i-1 ][  j-1 ][ 1 ]和 f [ i-1 ][ j ][ 0 ]转移

(至于为什么你们自己想)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 300
using namespace std;
int n,m,f[M][M][2],x,a[M],b[M],ans;
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=1;i<=n;i++){scanf("%d",&b[i]);}f[1][0][0]=a[1];f[1][0][1]=b[1];for(int i=2;i<=n;i++){for(int j=0;j<=m;j++){f[i][j][0]=f[i-1][j][0];f[i][j][1]=f[i-1][j][1];if(j>1) f[i][j][1]=max(f[i-1][j-2][0],f[i][j][1]);if(j>0) f[i][j][0]=max(f[i-1][j-1][1],f[i][j][0]);f[i][j][0]+=a[i];f[i][j][1]+=b[i];}}for(int i=0;i<=m;i++){ans=max(ans,max(f[n][i][0],f[n][i][1]));}printf("%d",ans);return 0;
}

然后是第三题

第三题大概是比较复杂的一道题了,关键就在于如何处理全排列的序号。
这道题一共分为两部分

第一部分,将给定的全排列转化成全排列的序号。

首先对于一个k,他的全排列一共有k!(k的阶乘)种排列。

设置一个变量 cnt=0,s[n]存储这个排列;

对于第 i 位,若有 k 个 j 满足: i < j <= n 且 s[ j ] > s[ i ],则我们需要将 cnt 加上 ( n - i )!* k。

为什么呢?对于某一个长为 N 的排列 , 一共分为 N 个部分,第 i 个部分是以 第 i 小的数为开头的排列,且这N个部分都有(N-1)!个排列。

也就是说,我们对于每一位,从这一位到结尾都看做一个未离散化的排列(依靠每一个数的大小关系把他们看做一个不是很严谨的排列) ,然后求这个排列在这些数“全排列”中的哪个部分,也就求得了需要从0向后跳个部分才能达到当前的部分。

这样我们就求得了给出序列的序号(编号)

我们将m加上cnt,得到k,就得到了最后应该输出的排列的编号。

第二部分,输出给定编号的全排列。

读到这里,你应该已经明白了,对于第 i 位,我们只要用 k 除以(n-i)的阶乘,就知道这个序列应该是位于第m个部分,然后输出在剩余的未输出过的数中第m小的数即可

所以说,我们只需要一个阶乘的预处理,然后瞎搞就好了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M
using namespace std;
LL n,m,s[22],p[22];
bool f[22];
LL cnt(LL x){LL co=0;for(LL i=x+1;i<=n;i++){if(p[i]<p[x]) co++;}return co;
}
LL check(LL x){LL co=0;for(LL i=1;i<=n;i++){if(f[i]) continue;co++;if(co==x){f[i]=true;return i;}}return -1;//这句话毫无意义
}
int main(){s[0]=1;scanf("%lld%lld",&n,&m);memset(f,true,sizeof(f));for(LL i=1;i<=n;i++) s[i]=s[i-1]*i;for(LL i=1;i<=n;i++) scanf("%lld",&p[i]),f[i]=false;for(LL i=1;i<=n;i++){m+=cnt(i)*s[n-i];}for(LL i=1;i<=n;i++){if(i>1) printf(" ");printf("%lld",check(m/s[n-i]+1));m%=s[n-i];}return 0;
}

第四道题,是一个特殊的二叉树,数字由于n<=10,我就只写了一个比较好些的但是比较慢的程序。

这个程序大概是这样,由于在先序遍历中,子节点一定在父节点后才出现,每一个节点的右子节点(如果有的话)总在它父节点的左子节点后出现,所以我只是暴力建树,枚举每个点的父节点,建完树之后用中序遍历检验建的这棵树是否正确即可,如果即可,再直接递归的计算。

然而,万万没想到,我最后还是栽了一个点应为这道题有^的操作(这里的^是指次方,而不是异或),我这里就暂时不写高精度了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<stack>
#define LL long long
#define M 20
using namespace std;
LL n,m,p[M],f[M],l[M],r[M],c[M],cnt;
string a,b;bool isd(char x){if(x>='0'&&x<='9') return true;return false;
}
int take(char x){if(isd(x)) return x-'0';if(x=='+') return -1;if(x=='-') return -2;if(x=='*') return -3;return -4;
}
bool search(LL x){if(p[x]>=0){cnt++;if(p[x]==c[cnt]) return true;return false;}if(l[x]==0||r[x]==0) return false;if(!search(l[x])) return false;cnt++;if(p[x]!=c[cnt]) return false;if(!search(r[x])) return false;return true;
}
LL pow(LL x,LL y){if(y==0) return 1;return x*pow(x,y-1);
}
LL calc(LL x){if(p[x]>=0) return p[x];if(p[x]==-1) return calc(l[x])+calc(r[x]);if(p[x]==-2) return calc(l[x])-calc(r[x]);if(p[x]==-3) return calc(l[x])*calc(r[x]);return pow(calc(l[x]),calc(r[x]));
}
void dfs(LL x){if(x==n+1){cnt=0;if(search(1)){printf("%lld",calc(1));exit(0);}return;}for(LL i=x-1;i>0;i--){if(p[i]>=0) continue;if(l[i]==0){l[i]=x,f[x]=i;dfs(x+1);l[i]=0,f[x]=0;}else if(r[i]==0){r[i]=x,f[x]=i;dfs(x+1);r[i]=0,f[x]=0;}}
}
int main(){scanf("%lld",&n);cin>>a;cin>>b;f[1]=1;f[2]=1;for(LL i=1;i<=n;i++){p[i]=take(a[i-1]);c[i]=take(b[i-1]);}dfs(2);return 0;
}

至于提高组的题解,欢迎大家访问http://www.cnblogs.com/xiao-ju-ruo-xjr/

转载于:https://www.cnblogs.com/OYJason/p/7608106.html

HDnoip2017题解相关推荐

  1. [JS][dfs]题解 | #迷宫问题#

    题解 | #迷宫问题# 题目链接 迷宫问题 题目描述 定义一个二维数组 N*M ,如 5 × 5 数组下所示: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 1, 1 ...

  2. [JS][dp]题解 | #打家劫舍(一)#

    题解 | #打家劫舍(一)# 题目链接 打家劫舍(一) 题目描述 描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家, ...

  3. [JS]题解 | #魔法数字#

    题解 | #魔法数字# 题目链接 魔法数字 题目描述 牛妹给牛牛写了一个数字n,然后又给自己写了一个数字m,她希望牛牛能执行最少的操作将他的数字转化成自己的. 操作共有三种,如下: 在当前数字的基础上 ...

  4. [JS]题解 | #岛屿数量#

    题解 | #岛屿数量# 题目链接 岛屿数量 题目描述 时间限制:1秒 空间限制:256M 描述 给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛.我们只考虑上下左右 ...

  5. [JS] 题解:提取不重复的整数

    题解:提取不重复的整数 https://www.nowcoder.com/practice/253986e66d114d378ae8de2e6c4577c1 时间限制:1秒 空间限制:32M 描述 输 ...

  6. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  7. [洛谷1383]高级打字机 题解

    题解 这道题一看就珂以用主席树啊 这是一道神奇的题目,那么我们先敲一个主席树,然后维护一个数组len,表示下一次应该在len + 1插入, 之后对于T操作,在上一个版本的len + 1上直接执行插入 ...

  8. luogu P1549 棋盘问题(2) 题解

    luogu P1549 棋盘问题(2) 题解 题目描述 在\(N * N\)的棋盘上\((1≤N≤10)\),填入\(1,2,-,N^2\)共\(N^2\)个数,使得任意两个相邻的数之和为素数. 例如 ...

  9. 【题解搬运】PAT_L1-009 N个数求和

    从我原来的博客上搬运.原先blog作废. (伪)水题+1,旨在继续摸清这个blog(囧 题目 就是求N个数字的和.麻烦的是,这些数字是以有理数"分子/分母"的形式给出的,你输出的和 ...

最新文章

  1. 使用文档自动保存功能
  2. c 语言程序设计教程 沈显君 答案,CD3计算机实践《C/C++语言程序设计》报告模板2.doc...
  3. 如何基于K8s构建下一代DevOps平台?
  4. 第三次学JAVA再学不好就吃翔(part101)--IO流
  5. 【JavaScript学习】JavaScript对象创建
  6. JAVA常见算法题(二十五)
  7. Java或Web中解决所有路径问题
  8. python对象转为字符串
  9. AD19 绘制PCB操作流程笔记
  10. ppt背景图片怎么设置?6步教你快速搞定!
  11. 第二章 02 天牛质感
  12. 使用Jhon工具破解Windows密码
  13. 【洛谷】P1488 肥猫的游戏(博弈论+全网最详细!!!)
  14. VUE之高德地图轨迹绘制与轨迹回放
  15. 《OpenGL ES 3.x游戏开发(下卷)》一2.4 展翅飞翔的雄鹰
  16. spi通信问题-有波形但无法获取正确数据:MOSI和SCK
  17. win10 常用命令
  18. redis 解决key是乱码问题,并清理
  19. 计算机意外重启或错误,Win7系统安装提示计算机意外重启或遇到错误解决方案...
  20. Java学习笔记 --- 多线程

热门文章

  1. Java 多线程 —— AQS 原理
  2. 计算机控制系统开关,电脑远程开关机控制器
  3. python内建函数测试对象身份_Python学习笔记 03 Python对象
  4. 算法竞赛入门经典 第二章总结
  5. php保存gbk字符串,php判断字符串gbk/utf8编码和转换
  6. react封装函数_react request.js 函数封装
  7. 二元相图软件_FactSage 软件教程 入门学习资料汇总
  8. java list拷贝_深入了解浅拷贝与深拷贝
  9. 卖金鱼的地方_1个水族店,5个周转箱,卖鲫鱼和泥鳅,老板对水族的热爱
  10. 计算机数日期,计算机如何计算两个日期之间的天数