1.ksum(ksum)

  1. 【问题描述】
  2. Peter喜欢玩数组。NOIP这天,他从Jason手里得到了大小为n的一个正整数
  3. 数组。
  4. Peter求出了这个数组的所有子段和,并将这n(n+)/2个数降序排序,他想
  5. 知道前k个数是什么。
  6. 【输入格式】
  7. 输入文件名为 ksum.in
  8. 输入数据的第一行包含两个整数 n k
  9. 接下来一行包含 n 个正整数,代表数组。
  10. 【输出格式】
  11. 输出文件名为 ksum.out
  12. 输出 k 个数,代表降序之后的前 k 个数,用空格隔开。
  13. 【输入输出样例】
  14. ksum.in
  15.  
  16. ksum.out
  17.  
  18. 【数据规模与约定】
  19. 对于所有数据,满足 ai≤^,kn(n+)/,n≤,k
  20. 测试点编号 n k

题目

tag:贪心

思路:每一个数都是正整数,意味着子段的大小一定小于父段,那我们必须先选择父段再选择子段。于是我们从整个数组1~n开始贪心,将每次选择的子段l~r再分成l+1~r和l~r-1两个更小的子段放入优先队列。但是,有可能会选择到重复的子段,我的处理是将左右端点哈希。记得求前缀和。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<cmath>
  6. #include<vector>
  7. #include<queue>
  8. #include<map>
  9. #define maxn 100010
  10. #define ll long long
  11. using namespace std;
  12. map<ll,int> Hash;
  13. ll sum[maxn],ans[maxn];
  14. int a[maxn],n,k,tot;
  15. struct NUM
  16. {
  17. int l,r;
  18. ll val;
  19. bool operator<(const NUM &x)const{return val<x.val;}
  20. };
  21. priority_queue<NUM>Q;
  22. void Push(NUM x)
  23. {
  24. ll num=1ll*x.l+1ll*x.r*;
  25. if(!Hash.count(num)){
  26. Hash[num]=;
  27. Q.push(x);
  28. }
  29. }
  30. int main()
  31. {
  32. //freopen("ksum.in","r",stdin);
  33. //freopen("ksum.out","w",stdout);
  34. scanf("%d%d",&n,&k);
  35. for(int i=;i<=n;++i){
  36. scanf("%d",&a[i]);
  37. sum[i]=sum[i-]+a[i];
  38. }
  39. NUM x;
  40. x.l=,x.r=n,x.val=sum[n];
  41. Push(x);
  42. while(){
  43. NUM now=Q.top();
  44. Q.pop();
  45. ans[++tot]=now.val;
  46. if(tot==k) break;
  47. int l=now.l,r=now.r;
  48. NUM x,y;
  49. x.l=l+,x.r=r;
  50. y.l=l,y.r=r-;
  51. x.val=sum[x.r]-sum[x.l-];
  52. y.val=sum[y.r]-sum[y.l-];
  53. Push(x);
  54. Push(y);
  55. }
  56. for(int i=;i<k;++i) cout<<ans[i]<<" ";
  57. cout<<ans[k]<<endl;
  58. return ;
  59. }

2.奇袭(raid)

  1. 【问题描述】
  2. 由于各种原因,桐人现在被困在Under World(以下简称UW)中,而UW马上
  3. 要迎来最终的压力测试——魔界入侵。
  4. 唯一一个神一般存在的Administrator被消灭了,靠原本的整合骑士的力量
  5. 是远远不够的。所以爱丽丝动员了UW全体人民,与整合骑士一起抗击魔族。
  6. UW的驻地可以隐约看见魔族军队的大本营。整合骑士们打算在魔族入侵
  7. 前发动一次奇袭,袭击魔族大本营!
  8. 为了降低风险,爱丽丝找到了你,一名优秀斥候,希望你能在奇袭前对魔
  9. 族大本营进行侦查,并计算出袭击的难度。
  10. 经过侦查,你绘制出了魔族大本营的地图,然后发现,魔族大本营是一个N
  11. ×N的网格图,一共有N支军队驻扎在一些网格中(不会有两只军队驻扎在一起)。
  12. 在大本营中,每有一个k×k(≤kN)的子网格图包含恰好k支军队,我们
  13. 袭击的难度就会增加1点。
  14. 现在请你根据绘制出的地图,告诉爱丽丝这次的袭击行动难度有多大。
  15. 【输入格式】
  16. 第一行,一个正整数N,表示网格图的大小以及军队数量。
  17. 接下来N行,每行两个整数,Xi,Yi,表示第i支军队的坐标。
  18. 保证每一行和每一列都恰有一只军队,即每一个Xi和每一个Yi都是不一样
  19. 的。
  20. 【输出格式】
  21. 一行,一个整数表示袭击的难度。
  22. 【输入输出样例】
  23. raid.in
  24.  
  25. raid.out
  26.  
  27. 【样例解释】
  28. 显然,分别以(,)和(,)为左上,右下顶点的一个子网格图中有3支军队,
  29. 这为我们的难度贡献了1点。
  30. 类似的子网格图在原图中能找出10个。
  31. 【数据范围】
  32. 对于30%的数据,N
  33. 对于60%的数据,N
  34. 对于100%的数据,N

题目

tag:分治、单调栈、玄学(雾)

思路:暴力可以二维前缀和或树状数组。这道题的模型有一定特殊性,每行每列都只有一个点,为了达到O(nlogn)的水平我们缩成一维。通过仔细观察发现,每一个符合条件的子段(子矩阵)都满足maxx-minx=len-1=r-l,原来是RMQ问题。

之后是玄学分治+单调栈,对于每个分治区间,用mid分成左右两侧,有四种情况,最小值和最大值在左左,左右,右左,右右,如果把子段反转,可以把右左和右右变成左右和左左,最后需要讨论两种情况,我们始终抓住函数的单调性来考虑,先以mid为分界线求出“前后缀最值”(min单减 ,max单增),既然要快速的查找,将公式移项,maxx-r=minx-l,我们造一个桶,将maxx-r放进去,让minx-l去找它对应的桶(建议结合代码理解)。接着是求“左左”的情况,为什么要满足j>mid?(注意,下面的几行我想了2h)像(1)、(1,2,3)这样的序列虽然满足条件,但不符合j>mid,他们会在分治的时候被解决,真正需要计算的是(1,5,2,3,4)这样,mid在2那里,1+(5-1)=5,1和5需要中间的2,3,4来补充,那么我们发现,所谓“左左”的情况并不是整个区间都在左哦。

接下来就是重头戏“左右”,也就是最小值在左最大值在右,之前求的前后缀最值就派上用场了,以最左端为标准求出满足条件的区间,最大值向右单增,也就是说越往右越大,越容易满足Rmax>Lmax,最小值相反(有些细节写在注释里了),遍历左区间,不断修改原来的范围,一一对应。

数组反转用stl的reserve,细节——(1,2,3,4,5)的mid在3,左(1,2,3),右(4,5),反转后(5,4,3,2,1)mid应该移到4的位置,此时左(5,4),右(3,2,1)。处理了另外两种情况。

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<stack>
  6. #define maxn 100010
  7. #define inf 1<<29
  8. #define ll long long
  9. using namespace std;
  10. int Lmax[maxn],Lmin[maxn],Rmax[maxn],Rmin[maxn],tong[maxn],a[maxn],n;
  11. ll cal(int l,int r,int mid)
  12. {
  13. ll ret();
  14. Lmax[mid]=Lmin[mid]=a[mid];
  15. Rmax[mid+]=Rmin[mid+]=a[mid+];
  16. for(int i=mid-;i>=l;--i){
  17. Lmax[i]=max(Lmax[i+],a[i]);
  18. Lmin[i]=min(Lmin[i+],a[i]);
  19. }
  20. for(int i=mid+;i<=r;++i){
  21. Rmax[i]=max(Rmax[i-],a[i]);
  22. Rmin[i]=min(Rmin[i-],a[i]);
  23. }
  24. for(int i=l;i<=mid;++i){
  25. int j=i+Lmax[i]-Lmin[i];
  26. if(j>mid&&Rmax[j]<Lmax[i]&&Rmin[j]>Lmin[i]) ret++;//最大值和最小值都在左边 由于j可能比n还大就导致数组需要开2倍
  27. }
  28. int p1=mid+,p2=mid;//p1 max指针 p2 min指针
  29. while(p1<=r&&Rmax[p1]<Lmax[l]) tong[Rmax[p1]-p1]--,p1++;//左不符合 右符合 最后指到第一个符合的
  30. while(p2<r&&Rmin[p2+]>Lmin[l]) p2++,tong[Rmax[p2]-p2]++;//左符合 右不符合 最后指到最后一个不符合的
  31. for(int i=l;i<=mid;++i){
  32. while(p1>mid+&&Rmax[p1-]>Lmax[i]) p1--,tong[Rmax[p1]-p1]++;//将原来不符合变为符合
  33. while(p2>mid&&Rmin[p2]<Lmin[i]) tong[Rmax[p2]-p2]--,p2--;//将符合变为不符合
  34. ret+=max(tong[Lmin[i]-i],);//万一是负的
  35. }
  36. for(int i=mid+;i<=r;++i) tong[Rmax[i]-i]=;//区间清零 不要脑子一热memset了
  37. return ret;
  38. }
  39. ll solve(int l,int r)
  40. {
  41. ll ret();
  42. if(l==r) return 1ll;
  43. int mid=(l+r)>>;
  44. ret=solve(l,mid)+solve(mid+,r);
  45. ret+=cal(l,r,mid);
  46. reverse(a+l,a+r+);//区间反转
  47. if((r-l+)&) mid--;//mid位置修正
  48. ret+=cal(l,r,mid);
  49. reverse(a+l,a+r+);
  50. return ret;
  51. }
  52. int main()
  53. {
  54. //freopen("raid.in","r",stdin);
  55. //freopen("raid.out","w",stdout);
  56. int x,y;
  57. scanf("%d",&n);
  58. for(int i=;i<=n;++i){
  59. scanf("%d%d",&x,&y);
  60. a[x]=y;//转一维
  61. }
  62. printf("%I64d\n",solve(,n));
  63. return ;
  64. }

3.十五数码(fifteen)

  1. 【题目描述】
  2. 给出起始顺序,要求通过 的移动(与上下左右交换),排成以下顺序:
  3.  
  4. 【输入格式】
  5. 从文件 fiften.in 中读入数据,四个数一行,共四行。
  6. 【输出格式】
  7. 输出到文件 fifteen.out 中。
  8. 输出最少移动次数。如果无解输出 No
  9. 【样例 输入】
  10.  
  11. 【样例 输出】
  12.  
  13. 【样例 输入】
  14.  
  15. 【样例 输出】
  16.  
  17. 【数据范围】
  18. 对于 %的数据,保证有解并且 Ans <=
  19. 对于 %的数据,保证有解并且 Ans <=
  20. 存在 %的数据无解。
  21. 对于 %的数据,如果有解,Ans <= ;

题目

tag:搜索

思路:状态很多,数字很多,哈希很困难。可以用双向广搜,然后正解是一堆位运算的IDA*,因为有点想法我尽量说自己的思路……IDA*嘛,我做了一些估价,初始状态到末状态每个数字的“曼哈顿距离”(坐标距),加起来就是最少要移动的次数(重要剪枝!),作为我们枚举deep的起点,终点是50,到50可以不做直接输出结果(但是没骗到分)。

dfs的过程是我们需要重点研究的。估价分单个数字和整体(感觉整体的更重要),简要来说,如果明显无法在剩余步数找到答案就不动了。有int全部套register,有if的尽量减少,有函数的尽量不用(重要剪枝!亲测swap能直接拖1s),小函数define掉(不过据说考试的时候不太保险?),还有个“手刀保护sdbh”避免来回移动(重要剪枝!从4^x到3^x的变化)。还有dalao教的exit(0)直接结束程序,biao脸的卡时还特判最后才A掉……

无解的情况需要求逆序数+空位到(4,4)的坐标距(因为0还要移过去啊……另外之后提到的逆序数包括空位的情况),那么问题来了为什么要求逆序数,我们看末状态的逆序数是15,一个奇数,而每次移动无论横纵的改变量都是偶数,奇+-偶=奇,初状态也必须是奇数才行。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<cmath>
  6. #include<ctime>
  7. #define aabs(x) (x>=0?x:-(x))
  8. #define ok(x,y) x>0&&x<5&&y>0&&y<5
  9. #define ll long long
  10. using namespace std;
  11. int dx[]={,,,-},dy[]={,,-,},mp[][],zb[][],dis[],deep,S,T,tot,start,sum;
  12. int cal(register int x,register int y){return (x-)*+y;}
  13. void dfs(register int f,register int DIS,register int x,register int y,register int sdbh)
  14. {
  15. if(clock()-start>=){
  16. if(deep<) printf("");
  17. else printf("");
  18. exit();
  19. }
  20. if(f==deep){
  21. if(!DIS){
  22. printf("%d\n",deep);
  23. exit();
  24. }
  25. return;
  26. }
  27. for(register int i=;i<;++i){
  28. register int X=dx[i]+x,Y=dy[i]+y,num=mp[X][Y];
  29. if(num!=sdbh&&ok(X,Y)&&deep-f>=dis[num]){
  30. mp[x][y]=num;
  31. mp[X][Y]=;
  32. register int change=aabs(x-zb[num][])+aabs(y-zb[num][])-aabs(X-zb[num][])-aabs(Y-zb[num][]);
  33. dis[num]+=change;
  34. if(DIS+change<=deep-f-) dfs(f+,DIS+change,X,Y,num);
  35. dis[num]-=change;
  36. mp[x][y]=;
  37. mp[X][Y]=num;
  38. }
  39. }
  40. }
  41. int main()
  42. {
  43. //freopen("fifteen.in","r",stdin);
  44. //freopen("fifteen.out","w",stdout);
  45. for(int i=;i<=;++i)
  46. for(int j=;j<=;++j)
  47. zb[cal(i,j)][]=i,zb[cal(i,j)][]=j;
  48. for(int i=;i<=;++i)
  49. for(int j=;j<=;++j){
  50. scanf("%d",&mp[i][j]);
  51. if(!mp[i][j]) S=i,T=j;
  52. else{
  53. dis[mp[i][j]]=aabs(i-zb[mp[i][j]][])+aabs(j-zb[mp[i][j]][]);
  54. tot+=dis[mp[i][j]];
  55. }
  56. }
  57. start=clock();
  58. deep=tot;
  59. for(int i=;i<=;++i)
  60. for(int j=;j<=;++j)
  61. for(int k=;k<=;++k)
  62. for(int l=;l<=;++l)
  63. if(cal(k,l)<cal(i,j))
  64. if(mp[k][l]>mp[i][j]) sum++;
  65. sum+=-S+-T;
  66. if(!(sum&)){
  67. puts("No");
  68. return ;
  69. }
  70. while(){
  71. if(deep==){
  72. printf("");
  73. return ;
  74. }
  75. dfs(,tot,S,T,);
  76. deep++;
  77. }
  78. return ;
  79. }

——————————并不华丽的分割线————————————

芒果君:这次考试好像没翻车然后刚才CF炸了……所以说自己不努力能怪谁呢……

冲刺Noip2017模拟赛6 解题报告——五十岚芒果酱的更多相关文章

  1. 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱

    题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n- 个路口,分别标上号,A 农场为 号,B 农场为 ...

  2. 冲刺Noip2017模拟赛1 解题报告——五十岚芒果酱

    题1 国际象棋(chess) [问题描述] 有N个人要参加国际象棋比赛,该比赛要进行K场对弈.每个人最多参加2场对弈,最少参加0场对弈.每个人都有一个与其他人都不相同的等级(用一个正整数来表示).在对 ...

  3. 冲刺Noip2017模拟赛5 解题报告——五十岚芒果酱

    1. 公约数(gcd) [问题描述] 给定一个正整数,在[,n]的范围内,求出有多少个无序数对(a,b)满足 gcd(a,b)=a xor b. [输入格式] 输入共一行,一个正整数n. [输出格式] ...

  4. 冲刺Noip2017模拟赛3 解题报告——五十岚芒果酱

    题1  素数 [问题描述] 给定一个正整数N,询问1到N中有多少个素数. [输入格式]primenum.in 一个正整数N. [输出格式]primenum.out 一个数Ans,表示1到N中有多少个素 ...

  5. 冲刺Noip2017模拟赛8 解题报告——五十岚芒果酱

    1.鼎纹 [问题描述] 据说鼎纹的 种制造 式是 铜模印出来的,这是我国古代劳动 智慧 的结晶.铜模印过的地 ,会留下深深的印记,经过时间的炼化,洗 练成历史的遗存. 聪明的古代劳动人民拥有一个 a ...

  6. 冲刺Noip2017模拟赛7 解题报告——五十岚芒果酱

    1.二叉树(binary) .二叉树 (binary.cpp/c/pas) [问题描述] 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: ()若左子树不空,则左子树上所有结点的值均小于它的根结 ...

  7. 冲刺Noip2017模拟赛4 解题报告——五十岚芒果酱

    题1 韬韬抢苹果(apple) [问题描述] 又到了收获的季节,树上结了许多韬韬,错了,是许多苹果,有很多个小韬韬都来摘苹 果.每个韬韬都想要最大的苹果,所以发生了争执,为了解决他们的矛盾,出题人定了 ...

  8. 20161005 NOIP 模拟赛 T2 解题报告

    beautiful 2.1 题目描述 一个长度为 n 的序列,对于每个位置 i 的数 ai 都有一个优美值,其定义是:找到序列中最 长的一段 [l, r],满足 l ≤ i ≤ r,且 [l, r] ...

  9. 【HHHOJ】NOIP模拟赛 玖 解题报告

    点此进入比赛 得分: \(100+20+100=220\)(还不错) 排名: \(Rank\ 16\) \(Rating\):\(+20\) \(T1\):[HHHOJ263]「NOIP模拟赛 玖」三 ...

随机推荐

  1. 第一篇博客-MVC路由简述

    一直念叨着写博客,可是迟迟不见下笔,工作到现在,技术长进了一点,但是记的东西都很杂,也没个思路,也不知道怎么去写一遍博客,现在在做MVC,写一点跟MVC有关的吧. 我们都知道MVC程序的所有请求都是先 ...

  2. 2、组件注册-@Configuration&@Bean给容器中注册组件

    2.组件注册-@Configuration&@Bean给容器中注册组件 2.1 创建maven项目 spring-annotation pom.xml文件添加 spring-context 依 ...

  3. Task异步

    快速示例 class Program { static void Main(string[] args) { //Console.WriteLine("main start..") ...

  4. JQuery实践--动画

    显示和隐藏没有动画的元素 使包装集里的元素隐藏 hide(speed,callback) speed:可选,速度.slow,normal,fastcallback:函数,可选,完成后调用的函数,无参数 ...

  5. 【算法题目】Leetcode算法题思路:两数相加

    在LeetCode上刷了一题比较基础的算法题,一开始也能解出来,不过在解题过程中用了比较多的if判断,看起来代码比较差,经过思考和改进把原来的算法优化了. 题目: 给出两个 非空 的链表用来表示两个非 ...

  6. /bin/sh: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8) centos7

    今天登陆centos 7 遇到一个 警告 /bin/sh: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8) bash : ...

  7. keydown([[data],fn]) 当键盘或按钮被按下时,发生 keydown 事件。

    keydown([[data],fn]) 概述 当键盘或按钮被按下时,发生 keydown 事件. 注释:如果在文档元素上进行设置,则无论元素是否获得焦点,该事件都会发生.直线电机滑台 参数 fnFu ...

  8. CF540D Bad Luck Island

    嘟嘟嘟 看到数据范围很小,就可以暴力\(O(n ^ 3)\)dp啦. 我们令\(dp[i][j][k]\)表示这三种人分别剩\(i, j, k\)个的概率.然后枚举谁挂了就行. 这里的重点在于两个人相 ...

  9. busTrace VS HW protocol analyzer - 好东西推荐

    最近在找PCIe/NVMe协议分析仪,发现一款软件分析仪:busTRACE,非常不错的工具,对于从事协议开发的同胞们,是个福利,下面把硬件和软件两种分析仪的各自的优势比较了一下(来自busTrace文 ...

  10. masm 编译贪吃蛇游戏

    code: ;TITLE GAME4TH PAGE , STSEG SEGMENT DB DUP () STSEG ENDS ;----------------------------------- ...