HDnoip2017题解
那么,作为一名初入信息竞赛的选手,我也试着开始用博客记录自己的学习历程,那么这篇文章先简单介绍一下我自己吧。
本人开始学习信息学大概以来,主要都是用的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==) return x/k;
return x/k+;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=m;i++){
scanf("%d%d",&x,&y);
a[x]++;
a[y]--;
}
for(int i=;i<=n+;i++){
tmp+=a[i];
ans=max(ans,need(tmp));
}
ans=min(ans,need(m));
printf("%d",ans);
return ;
}
第二题,一个简单的动态规划
设 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][],x,a[M],b[M],ans;
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=;i<=n;i++){
scanf("%d",&b[i]);
}
f[][][]=a[];
f[][][]=b[];
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
f[i][j][]=f[i-][j][];
f[i][j][]=f[i-][j][];
if(j>) f[i][j][]=max(f[i-][j-][],f[i][j][]);
if(j>) f[i][j][]=max(f[i-][j-][],f[i][j][]);
f[i][j][]+=a[i];
f[i][j][]+=b[i];
}
}
for(int i=;i<=m;i++){
ans=max(ans,max(f[n][i][],f[n][i][]));
}
printf("%d",ans);
return ;
}
然后是第三题
第三题大概是比较复杂的一道题了,关键就在于如何处理全排列的序号。
这道题一共分为两部分
第一部分,将给定的全排列转化成全排列的序号。
首先对于一个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[],p[];
bool f[];
LL cnt(LL x){
LL co=;
for(LL i=x+;i<=n;i++){
if(p[i]<p[x]) co++;
}
return co;
}
LL check(LL x){
LL co=;
for(LL i=;i<=n;i++){
if(f[i]) continue;
co++;
if(co==x){
f[i]=true;
return i;
}
}
return -;//这句话毫无意义
}
int main(){
s[]=;
scanf("%lld%lld",&n,&m);
memset(f,true,sizeof(f));
for(LL i=;i<=n;i++) s[i]=s[i-]*i;
for(LL i=;i<=n;i++) scanf("%lld",&p[i]),f[i]=false;
for(LL i=;i<=n;i++){
m+=cnt(i)*s[n-i];
}
for(LL i=;i<=n;i++){
if(i>) printf(" ");
printf("%lld",check(m/s[n-i]+));
m%=s[n-i];
}
return ;
}
第四道题,是一个特殊的二叉树,数字由于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>=''&&x<='') return true;
return false;
}
int take(char x){
if(isd(x)) return x-'';
if(x=='+') return -;
if(x=='-') return -;
if(x=='*') return -;
return -;
}
bool search(LL x){
if(p[x]>=){
cnt++;
if(p[x]==c[cnt]) return true;
return false;
}
if(l[x]==||r[x]==) 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==) return ;
return x*pow(x,y-);
}
LL calc(LL x){
if(p[x]>=) return p[x];
if(p[x]==-) return calc(l[x])+calc(r[x]);
if(p[x]==-) return calc(l[x])-calc(r[x]);
if(p[x]==-) return calc(l[x])*calc(r[x]);
return pow(calc(l[x]),calc(r[x]));
}
void dfs(LL x){
if(x==n+){
cnt=;
if(search()){
printf("%lld",calc());
exit();
}
return;
}
for(LL i=x-;i>;i--){
if(p[i]>=) continue;
if(l[i]==){
l[i]=x,f[x]=i;
dfs(x+);
l[i]=,f[x]=;
}
else if(r[i]==){
r[i]=x,f[x]=i;
dfs(x+);
r[i]=,f[x]=;
}
}
}
int main(){
scanf("%lld",&n);
cin>>a;
cin>>b;
f[]=;
f[]=;
for(LL i=;i<=n;i++){
p[i]=take(a[i-]);
c[i]=take(b[i-]);
}
dfs();
return ;
}
至于提高组的题解,欢迎大家访问http://www.cnblogs.com/xiao-ju-ruo-xjr/
HDnoip2017题解的更多相关文章
- [HDNOIP2017提高组]题解
(送给外省的同学们:HD = 海淀) [HDNOIP201701]小鱼干 试题描述 小喵喵有 n 个小鱼干排成一列,其中第 i 个小鱼干有两种属性,美味度 ai 和特殊度 bi. 现在小喵喵要吃掉一些 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
随机推荐
- jQuery实现web页面固定列表搜索
1.需求分析:现在有一个数据展示列表页面,列表内容固定,使用jQuery在固定的列表中实现搜索功能. 2.核心代码: <!-- 添加jquery库 --> <script type= ...
- 电脑IP地址被占用如何释放?
回车后,关机,等待5分钟左右再开机,就释放掉了.
- JS或jQuery实现一组复选框的全选和取消全选?
//1.JS方式实现:checkbox 全选/取消全选 var isCheckAll = false; function swapCheck() { if (isCheckAll) { ...
- 设置MySQL最大连接数
<pre name="code" class="sql">在使用MySQL数据库的时候,经常会遇到这么一个问题,就是"Can not co ...
- django celery的分布式异步之路(二) 高并发
当你跑通了前面一个demo,博客地址:http://www.cnblogs.com/kangoroo/p/7299920.html,那么你的分布式异步之旅已经起步了. 性能和稳定性是web服务的核心评 ...
- 数组去重方法(ES6)
let arrayBefore = [1,3,3,2,1,5,2,1]; //去重之前的数组 Array.prototype.dedupe = function (){ //去重函数 返回去重后的数组 ...
- leetcode 697. Degree of an Array
题目: Given a non-empty array of non-negative integers nums, the degree of this array is defined as th ...
- win10 uwp 绑定静态属性
Jasoon 大神问,如何绑定静态属性. 我们经常有静态属性,那么我们如何绑定 假如我们的ViewModel有一个静态属性 public static string CVTE { set; get; ...
- java基础---字符串string
1.字符创的概念 java字符串就是Unicode字符序列.例如,串“Java\u2122”由5个Unicode字符J.a.v.a和TM.java没有内置的字符串类型,而是在标准库Java类库中提供了 ...
- PE格式第九讲,资源表解析
PE格式第九讲,资源表解析 一丶熟悉Windows管理文件的方法 首先,为什么标题是这个,主要是为了下边讲解资源方便,因为资源结构体很乱.如果直接拿出来讲解,那么就会很晕. 1.windows管理文件 ...