NOIP2017提高组模拟赛 9 (总结)##

第一题 星星

  1. 天空中有N(1N400)颗星,每颗星有一个唯一的坐标(x,y),(1x,y N)。请计算可以覆盖至少K(1KN)颗星的矩形的最小面积。矩形的边必须平行于X轴或Y轴,长度必须为正整数。星如果在矩形的边上,也认为它是属于矩形内的。

  思路:枚举矩形左上角的x,以及在x轴上的长度(矩形的长),然后单调的往下扫。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. #define imax(a,b) ((a>b)?(a):(b))
  5. #define imin(a,b) ((a<b)?(a):(b))
  6. typedef long long ll;
  7. using namespace std;
  8. int n,ne,ans;
  9. int sum[410][410];
  10. bool d[410][410];
  11. int main()
  12. {
  13. freopen("a.in","r",stdin);
  14. freopen("a.out","w",stdout);
  15. scanf("%d%d",&n,&ne);
  16. ans=n*n;
  17. for(int i=1;i<=n;i++)
  18. {
  19. int a,b;
  20. scanf("%d%d",&a,&b); d[a][b]=1;
  21. }
  22. for(int i=1;i<=n;i++)
  23. {
  24. sum[i][0]=0;
  25. for(int j=1;j<=n;j++) sum[i][j]=sum[i][j-1]+(d[i][j]?1:0);
  26. }
  27. for(int ll=1;ll<=n;ll++)
  28. {
  29. for(int i=1;i<=n-ll+1;i++)
  30. {
  31. int fr=1,la=1,ss=sum[fr][i+ll-1]-sum[fr][i-1];
  32. while(la<=n)
  33. {
  34. while(ss<ne)
  35. {
  36. la++; ss+=sum[la][i+ll-1]-sum[la][i-1];
  37. if(la>n) break;
  38. }
  39. if(la>n) break;
  40. ans=imin(ans,(la-fr+1)*ll);
  41. ss-=sum[fr][i+ll-1]-sum[fr][i-1]; fr++;
  42. }
  43. }
  44. }
  45. printf("%d\n",ans);
  46. return 0;
  47. }

第二题 战争

  1. X国和Y国是死对头,X国有N个炮台, Y国有M个基地和K个发电站,炮台、基地、发电站所在的位置的坐标都是整数。Y国的每个发电站能对距离其L以内(包括L)的基地供电。X国的每个炮台都可以发射无限次,每次发射可以击毁一个基地或者一个发电站,消耗的能量为两者距离的平方,这里的距离是欧几里德距离。X国决定要摧毁Y国的所有基地,我们说Y国的某个基地被摧毁的条件是:基地本身被直接摧毁或者对其供电的所有发电站被击。
  2. X国摧毁Y国所有基地需要消耗的总能量最小是多少。
  3. 提示:点(X1,Y1)和点(X2,Y2)的欧几里德距离是:
  4. dis = sqrt((X2-X1)*(X2-X1)+(Y2-Y1)*(Y2-Y1)).

  经典的网络流01模型,直接构图,跑一次dinic就行了。

  S向各个基地基地bi连边,代价为距离基地bi最近的炮台之间的距离。

  各个电厂向T连边,代价为距离电厂ci最近的炮台之间的距离。

  若电厂ci可以供电给基地dj,那么基地dj连向电厂ci,代价为∞。

  图的S到T的最小割即为answer。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. #define imax(a,b) ((a>b)?(a):(b))
  6. #define imin(a,b) ((a<b)?(a):(b))
  7. typedef long long ll;
  8. using namespace std;
  9. const int N=50;
  10. const int M=15000;
  11. const int oo=1e9;
  12. struct data { int x,y; } ad[N+10],bd[N+10],cd[N+10];
  13. int to[M],h[M],ne[M],val[M],tt,S,T;
  14. int vis[M],lev[M],q[M];
  15. int an,bn,cn,L,bfstime;
  16. void read(int n,data* A)
  17. {
  18. for(int i=1;i<=n;i++) scanf("%d",&A[i].x);
  19. for(int i=1;i<=n;i++) scanf("%d",&A[i].y);
  20. }
  21. void add(int a,int b,int c)
  22. {
  23. to[++tt]=b; ne[tt]=h[a]; val[tt]=c; h[a]=tt;
  24. to[++tt]=a; ne[tt]=h[b]; val[tt]=0; h[b]=tt;
  25. }
  26. int dis(data A,data B) { return ((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)); }
  27. void init()
  28. {
  29. scanf("%d%d%d%d",&an,&bn,&cn,&L);
  30. read(an,ad); read(bn,bd); read(cn,cd);
  31. tt=1; S=110; T=111;
  32. for(int i=1;i<=bn;i++)
  33. {
  34. int dd=oo;
  35. for(int j=1;j<=an;j++) dd=imin(dd,dis(ad[j],bd[i]));
  36. add(S,i,dd);
  37. }
  38. for(int i=1;i<=cn;i++)
  39. {
  40. int dd=oo;
  41. for(int j=1;j<=an;j++) dd=imin(dd,dis(ad[j],cd[i]));
  42. add(50+i,T,dd);
  43. }
  44. int ml=L*L;
  45. for(int i=1;i<=bn;i++)
  46. {
  47. for(int j=1;j<=cn;j++)
  48. if(dis(bd[i],cd[j])<=ml) add(i,50+j,oo);
  49. }
  50. }
  51. bool bfs()
  52. {
  53. lev[S]=1; vis[S]=++bfstime;
  54. int he=1,ta=1; q[1]=S;
  55. while(he<=ta)
  56. {
  57. int u=q[he++];
  58. for(int p=h[u];p;p=ne[p])
  59. {
  60. int v=to[p];
  61. if(vis[v]==bfstime || !val[p]) continue;
  62. q[++ta]=v; vis[v]=bfstime; lev[v]=lev[u]+1;
  63. }
  64. }
  65. return (vis[T]==bfstime);
  66. }
  67. int dfs(int now,int maxf)
  68. {
  69. int ret=0,t=0;
  70. if(!maxf || now==T) return maxf;
  71. for(int p=h[now];p;p=ne[p])
  72. {
  73. int v=to[p];
  74. if(lev[v]!=lev[now]+1 || !val[p]) continue;
  75. t=dfs(v,imin(maxf,val[p]));
  76. ret+=t; maxf-=t;
  77. val[p]-=t; val[p^1]+=t;
  78. }
  79. if(!maxf) lev[now]=-1;
  80. return ret;
  81. }
  82. int dinic()
  83. {
  84. int ret=0;
  85. while(bfs()) ret+=dfs(S,oo);
  86. return ret;
  87. }
  88. int main()
  89. {
  90. freopen("b.in","r",stdin);
  91. freopen("b.out","w",stdout);
  92. init();
  93. printf("%d\n",dinic());
  94. return 0;
  95. }

第三题 染色树

  1. 一棵共含有X个结点的树,结点编号1X,根结点编号是1。有Y种不同的颜色,颜色编号从1Y
  2. 现在给每个结点都染上一种颜色,整颗树染色后满足:
  3. 1、对于编号是i的颜色,整颗树当中,至少有一个结点被染成了颜色i
  4. 2、根结点必须被染成1号颜色,而且整颗树当中,恰好要有Z个结点被染成1号颜色。
  5. 染色过程结束后,现在要计算染色的总代价,总代价等于每一条边的代价之和,那么怎么计算一条边的代价呢?
  6. 不妨设结点a与结点b之间有一条边,该边的权重是W
  7. 1、如果结点a和结点b最终被染成不同的颜色,那么ab之间的那条边的代价等于0
  8. 2、如果结点a和结点b最终被染成相同的颜色,那么ab之间的那条边的代价等于W
  9. 现在的问题是:在满足上述要求的前提下,染色树最小的总代价是多少?如果无法完成染色的任务,输出-1

  显然的,这是一道树形DP题(DP做的有点多-_-||),X,Y,Z好像都很大。直接做无疑是超时的。

  那么想考虑一下,answer=-1的情况。每个节点都可以是任意颜色(只是会有代价而已),唯一不满足的情况就是Z>X-Y+1(极限情况)。

  这是一棵树(这很重要),那么只需要两种颜色就可以使整棵树的任意x和x的父亲的颜色不同。

  又多了一个颜色1恰好为Z的限制条件,那么也只需要3种颜色就行了(多余的颜色是没任何作用的)。

  时间复杂度:O(9N³)

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. #define imax(a,b) ((a>b)?(a):(b))
  5. #define imin(a,b) ((a<b)?(a):(b))
  6. typedef long long ll;
  7. using namespace std;
  8. const int oo=1e9;
  9. const int M=700;
  10. int X,Y,Z,ans;
  11. int to[M],ne[M],h[M],val[M],tt;
  12. int f[302][4][302];
  13. void add(int a,int b,int c)
  14. {
  15. to[++tt]=b; ne[tt]=h[a]; h[a]=tt; val[tt]=c;
  16. to[++tt]=a; ne[tt]=h[b]; h[b]=tt; val[tt]=c;
  17. }
  18. void dfs(int x,int fa)
  19. {
  20. for(int i=1;i<=Y;i++)
  21. {
  22. for(int j=0;j<=Z;j++) f[x][i][j]=oo;
  23. if(i==1) f[x][i][1]=0; else f[x][i][0]=0;
  24. }
  25. for(int p=h[x];p;p=ne[p])
  26. {
  27. int v=to[p];
  28. if(v==fa) continue;
  29. dfs(v,x);
  30. for(int i=1;i<=Y;i++)
  31. for(int j=Z;j>=0;j--)
  32. {
  33. int bes=oo;
  34. for(int g=1;g<=Y;g++) bes=imin(bes,f[v][g][0]+(i==g?val[p]:0));
  35. f[x][i][j]=imin(oo,f[x][i][j]+bes);
  36. for(int k=1;k<=j;k++)
  37. {
  38. int yu=oo;
  39. for(int g=1;g<=Y;g++) yu=imin(yu,f[v][g][k]+(i==g?val[p]:0));
  40. f[x][i][j]=imin(f[x][i][j],f[x][i][j-k]+yu);
  41. }
  42. }
  43. }
  44. }
  45. int main()
  46. {
  47. freopen("c.in","r",stdin);
  48. freopen("c.out","w",stdout);
  49. scanf("%d%d%d",&X,&Y,&Z); tt=1;
  50. if(Z>X-Y+1) printf("-1\n"); else
  51. {
  52. Y=imin(Y,3);
  53. for(int i=1;i<X;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); }
  54. dfs(1,1);
  55. printf("%d\n",f[1][1][Z]);
  56. }
  57. return 0;
  58. }

  终于拿了一次AK了(虽然这次的题目有点水……)。

NOIP2017提高组模拟赛 9 (总结)的更多相关文章

  1. NOIP2017提高组 模拟赛15(总结)

    NOIP2017提高组 模拟赛15(总结) 第一题 讨厌整除的小明 [题目描述] 小明作为一个数学迷,总会出于数字的一些性质喜欢上某个数字,然而当他喜欢数字k的时候,却十分讨厌那些能够整除k而比k小的 ...

  2. NOIP2017提高组 模拟赛13(总结)

    NOIP2017提高组 模拟赛13(总结) 第一题 函数 [题目描述] [输入格式] 三个整数. 1≤t<10^9+7,2≤l≤r≤5*10^6 [输出格式] 一个整数. [输出样例] 2 2 ...

  3. NOIP2017提高组模拟赛 10 (总结)

    NOIP2017提高组模拟赛 10 (总结) 第一题 机密信息 FJ有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的 ...

  4. NOIP2017提高组模拟赛 8(总结)

    NOIP2017提高组模拟赛 8(总结) 第一题 路径 在二维坐标平面里有N个整数点,Bessie要访问这N个点.刚开始Bessie在点(0,0)处. 每一步,Bessie可以走到上.下.左.右四个点 ...

  5. NOIP2017提高组模拟赛 7(总结)

    NOIP2017提高组模拟赛 7(总结) 第一题 斯诺克 考虑这样一个斯诺克球台,它只有四个袋口,分别在四个角上(如下图所示).我们把所有桌子边界上的整数点作为击球点(除了4个袋口),在每个击球点我们 ...

  6. NOIP2017提高组模拟赛5 (总结)

    NOIP2017提高组模拟赛5 (总结) 第一题 最远 奶牛们想建立一个新的城市.它们想建立一条长度为N (1 <= N <= 1,000,000)的 主线大街,然后建立K条 (2 < ...

  7. NOIP2017提高组模拟赛4 (总结)

    NOIP2017提高组模拟赛4 (总结) 第一题 约数 设K是一个正整数,设X是K的约数,且X不等于1也不等于K. 加了X后,K的值就变大了,你可以重复上面的步骤.例如K= 4,我们可以用上面的规则产 ...

  8. 计蒜客NOIP2017提高组模拟赛(三)day1

    火山喷发 火山喷发对所有附近的生物具有毁灭性的影响.在本题中,我们希望用数值来模拟这一过程. 在环境里有 n 个生物分别具有 A​1​​,A​2​​,⋯,A​n​​点生命值,一次火山喷发总计 MM 轮 ...

  9. 计蒜客NOIP2017提高组模拟赛(四)day1

    T1:小X的质数 小 X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感.小 X 认为,质数是一切自然数起源的地方. 在小 X 的认知里,质数是除了本身和 1 以外,没有其他因数的 ...

随机推荐

  1. 0x17 二叉堆

    优先队列太好用了手写啥呀 poj1456 经过贪心专题的洗礼以后这题根本就不叫题啊...按时间大到小排每次取最大就好 #include<cstdio> #include<iostre ...

  2. hdoj--1018--Big Number(简单数学)

    Big Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  3. EMC存储划分lun过程

    下图是EMC存储系统示意图: 若将lun打散重建,需按以下步骤进行: 1. 在Storage Groups上点右键选择Select Luns,在打开的窗口中,将右边Selected Lun项下的lun ...

  4. Extjs 常见错误

    http://blog.csdn.net/lc448986375/article/details/8082014

  5. MVC 全局异常处理(适用多人操作)

    自定义特性: using System; using System.Collections.Generic; using System.Linq; using System.Web; using Sy ...

  6. ROS命令参考

    前言:整理一些ROS常用命令,参考自:<ROS机器人编程>. 一.ROS执行命令 二.ROS信息命令 三.ROS catkin命令 四.ROS功能包命令 -END-

  7. C# 正则表达式

    C# 正则表达式 正则表达式 是一种匹配输入文本的模式..Net 框架提供了允许这种匹配的正则表达式引擎.模式由一个或多个字符.运算符和结构组成. 定义正则表达式 下面列出了用于定义正则表达式的各种类 ...

  8. 弹出ifame页面(jquery.reveal.js)

    <body> <a data-reveal-id="myModalDailyModify" data-animation="fade" tit ...

  9. win32应用禁止改变窗口大小方法

    一种简单的处理方法是在调用CreateWindow函数时指定的窗口样式中去掉WS_THICKFRAME样式. 如果你使用的样式中已经包含该样式,例如WS_OVERLAPPEDWINDOW,我们可以將W ...

  10. 第一次接触Arduino

    1.百度百科: Arduino包含两个主要的部分:硬件部分是可以用来做电路连接的Arduino电路板:另外一个则是 Arduino IDE,你的计算机中的程序开发环境.你只要在IDE中编写程序代码,将 ...