计蒜客\(2019CSP\)比赛第二场

巧妙爆零这场比赛(我连背包都不会了\(QWQ\)

\(T1\) \(Too\) \(Young\)

大学选课真的是一件很苦恼的事呢!

\(Marco\):“我要两年毕业!我要选尽量多的学分!这些课统统选上!”

长者:"你啊,\(Too Young\)!你看看作业量,你做的完吗?"

\(Marco\)(笑容逐渐消失\(.gif\)):”那可咋整啊?“

长者:"还能咋整?退课呗!“

已知 \(Marco\) 选了 \(N(1 \leq N \leq 500)\)门课,每门课有学分 \(w_i\),劳累度 \(v_i\)和挂科概率 \(p_i\);

其中,\(w_i\)为 \([1,5]\) 范围内的一个正整数,\(v_i\)是 \(int\) 范围内正整数, \(p_i\)是 \([0,1]\)范围内小数;

现在 \(Marco\) 想退掉某些课使得自己的劳累度尽量小,但是,如果 \(Marco\) 的学分总数达不到给定的 \(MINX\),他会被退学。

\(Marco\)想知道,在期望学分大于等于 \(MINX\) 的情况下,他的最小劳累度是多少。

注意:如果一门课挂科,\(Marco\) 将付出 \(v_i\)的劳累度但是无法获得相应学分;否则,\(Marco\) 将付出 \(v_i\)的劳累度并收获 \(w_i\)的学分。

输入格式

第一行一个正整数 \(N\) 表示课程数量

接下来 \(N\) 行,每行空格分开的 \(3\) 个数 \(w_i,v_i\)和 \(p_i\),含义如题面所述

最后一行一个正整数 \(MINX\) 表示所需最小学分。

输出格式

一行一个正整数表示最小劳累度。

数据范围

本题共 \(10\) 个测试点,每个测试点 \(10\) 分。

对于 \(10\%\) 的数据,\(1 \leq N \leq 10\)

对于 \(30\%\) 的数据,\(1 \leq N \leq 20\)

对于另外 \(20\%\) 的数据,\(p_i=0\)

对于 \(100\%\) 的数据,

\(1 \leq N \leq 500\) ,

\(w_i\)是正整数且 \(1 \leq wi \leq 5\),

\(p_i\)最多包含 \(2\) 位小数且 \(0 \leq pi \leq 1\),

\(v_i\)是 \(int\) 范围内正整数.

保证全选的情况下 \(Marco\) 不会被退学。

题解:

一眼背包题……

可以发现学分就是背包问题里的费用(体积,疲劳度就是背包问题里的价值,而我们的最终目的有所改变,不再是满足小于等于背包容量的最大价值,而是大于等于背包容量的最小价值

有一些细节需要注意

1.精度问题:

我们在背包问题中,物品的体积一定是个整数,但是在这道题里,它却可能是个小数,怎么办呢

我们发现\(p\)是一个二位小数,只要乘一个\(100\),就会变成一个整数

但是仍须注意的是,在转\(int\)以前(乘\(100\)以前,一定要加一个\(0.1\),不然会因为精度丢失而导致学分数减少

关于该精度问题,计蒜客杜昊老师给出的答复:(我超喜欢这位老师的-W-

因为 double 浮点数在计算机内部保存的时候并不一定是一个准确的值,例如 100 保存的时候有可能是 99.9999999 ,为了防止这种情况下我强制截断成 int 的时候使得 100 变成 99,所以 +0.01,因为这个值对我的整数部分是不会有影响的

2.上下界处理问题:

这道题不同于普通的背包,我们要在所有超出背包体积的价值里取一个最小值,所以我们需要求出所有的可能体积,而不是只求最小学分

请恰代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define rint register int
  4. int n, MIN;
  5. long long sum, w[510], v[510], dp[250010], ans = ( 1ll << 60ll );
  6. inline int read( void ){
  7. int re = 0, f = 1; char ch = getchar();
  8. while( ch > '9' || ch < '0' ){
  9. if( ch == '-' ) f = -1;
  10. ch = getchar();
  11. }
  12. while( ch >= '0' && ch <= '9' ){
  13. re = re * 10 + ch - '0';
  14. ch = getchar();
  15. }
  16. return re * f;
  17. }
  18. int main( void ){
  19. n = read();
  20. for( rint i = 1; i <= n; i++ ){
  21. w[i] = read(); v[i] = read();
  22. double p; scanf( "%lf", &p );
  23. w[i] *= ( int )( 100.0 * ( 1.0 * ( 1.0 - p ) ) + 0.1 );
  24. sum += w[i];
  25. }
  26. MIN = read(); MIN *= 100;
  27. for( rint i = 1; i <= sum; i++ ) dp[i] = ( 1ll << 60ll );
  28. sum = 0; int j = 0;
  29. for( rint i = 1; i <= n; i++ ){
  30. for( sum += w[i], j = sum; j >= w[i]; j-- ){
  31. dp[j] = min( dp[j], dp[j - w[i]] + v[i] );
  32. }
  33. }
  34. for( rint i = MIN; i <= sum; i++ ){
  35. ans = min( ans, dp[i] );
  36. }
  37. printf( "%lld", ans );
  38. return 0;
  39. }

\(T2\) \(Too\) \(Simple\)

打题干是最痛苦的

长者:“说你 \(Too Young\) 你还不相信,看这道题你会不会做!”

有一个二维平面,\(x,y\) 坐标范围都是 \([-10^9,10^9]\) ,平面上有 \(N\) 个特殊位置 \((X_i,Y_i)\) ,每次可以向四连通(上,下,左,右)的格子走一步,定义 \((S,T)\) 到 \((X_i,Y_i)\)的距离为从 \((S,T)(S,T)\) 走到 \((X_i,Y_i)\) 的最小步数。 \(Q\) 次询问,给定 \((S,T)\) ,求这个点到所有特殊位置的距离之和。

数据范围:\(1 \leq N,Q \leq 10^6 1 \leq S,T,X_i,Y_i \leq 10^9\)

\(Marco\):“这是哪里来的大水题啊?我用脚趾头都能把这题切掉!”

长者:“你啊,\(Too Young,Too Simple\)!其他条件不变,如果把条件中的四连通改成八连通,你还会做吗?”

\(Marco\) 陷入了沉思……于是,他找来你帮他解决这个问题。

注:八连通的定义:与 \((x,y)\) 八连通的格子分别为 \((x,y+1),(x,y-1),(x+1,y),(x-1,y),(x-1,y-1),(x-1,y+1),(x+1,y-1),(x+1,y+1)\)。

输入格式

第一行一个数字 \(T\) 表示数据组数;

对于每组数据,

第一行两个数字 \(N,Q\) 分别表示 特殊位置数量和询问次数。

接下来 \(N\) 行,每行两个数字 \(X_i,Y_i\)表示特殊位置坐标;

接下来 \(Q\) 行,每行两个数字 \(S,T\) 表示询问起点坐标。

输出格式

对于每组数据输出 \(Q\) 行,

每行一个整数表示这个点到特殊位置的距离之和。

数据范围

本题共 \(5\) 个测试点,每个测试点 \(20\) 分。

对于 \(20\%\) 的数据,\(T=1\), \(1 \leq N,Q \leq 5000, 1 \leq S,T,X_i,Y_i \leq 1000\)

对于 \(40\%\) 的数据,所有数据中 \(N*Q\) 的总和不超过 \(5*10^7\)

对于另外 \(20\%\) 的数据,\(T=1\),\(1 \leq S,T,X_i,Y_i \leq 1000\)

对于 \(100\%\) 的数据,\(N\) 的总和和 \(Q\) 的总和均不超过 \(10^6\),\(1 \leq S,T,X_i,Y_i \leq 10^91≤S\)

题解

切比雪夫距离与曼哈顿距离的转化,不懂的百度请(很简单的

将切比雪夫距离转化之后,我们就不需要比较大小了,直接算出曼哈顿距离来,再经过一些转化即为切比雪夫距离,也就是乘个\(2\)。

将切比雪夫距离转化之后,

切比雪夫距离求的是两个坐标的\(x,y\)差值的的较大者,而曼哈顿距离求的是两坐标差值的和,即\(( x_1 - x_2) + ( y _ 1 - y _ 2)\)

将读入的点变为\(( x + y, x - y)\),然后求曼哈顿距离,求出来的就是原来点对的切比雪夫距离

但是一个一个的暴力求距离会\(TLE\),所以我们要想一些办法

前缀和

可以把已知点按\(x\)排序,然后再按\(y\)排一次,这样只要二分查找到询问点的位置,就可以很快解决了

这个前缀和是一维的,原因很好想,因为曼哈顿距离的\(xy\)没有关系,先求出\(x\)然后再求出\(y\),两者加起来就好了

\(update\) \(2019.11.13\)

终于过了,计蒜客的杜昊老师实在是太好了\(QWQ\),他帮我看了三次代码了\(QWQ\),那八十分是因为忘开\(longlong\)了……

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define rint register int
  4. #define ll long long
  5. int n, q, T;
  6. ll x[1000010], y[1000010], sumx[1000010], sumy[1000010];
  7. ll ans;
  8. inline int read( void ){
  9. int re = 0, f = 1; char ch = getchar();
  10. while( ch > '9' || ch < '0' ){
  11. if( ch == '-' ) f = -1;
  12. ch = getchar();
  13. }
  14. while( ch >= '0' && ch <= '9' ){
  15. re = re * 10 + ch - '0';
  16. ch = getchar();
  17. }
  18. return re * f;
  19. }
  20. int main( void ){
  21. T = read();
  22. while( T-- ){
  23. n = read(); q = read();
  24. for( rint i = 1; i <= n; i++ ){
  25. int t1, t2;
  26. t1 = read(); t2 = read();
  27. x[i] = t1 + t2; y[i] = t1 - t2;
  28. }
  29. sort( x + 1, x + 1 + n ); sort( y + 1, y + 1 + n );
  30. for( rint i = 1; i <= n; i++ ){
  31. sumx[i] = sumx[i - 1] + x[i]; sumy[i] = sumy[i - 1] + y[i];
  32. }
  33. for( rint i = 1; i <= q; i++ ){
  34. ans = 0;
  35. ll qx, qy; qx = read(); qy = read();
  36. ll lowx, lowy;
  37. lowx = upper_bound( x + 1, x + 1 + n, qx + qy ) - x - 1;
  38. lowy = upper_bound( y + 1, y + 1 + n, qx - qy ) - y - 1;
  39. ans += ( ( ( lowx * ( qx + qy ) ) - sumx[lowx] ) + ( sumx[n] - sumx[lowx] ) - ( ( n - lowx ) * ( qx + qy ) ) );
  40. ans += ( ( ( lowy * ( qx - qy ) ) - sumy[lowy] ) + ( sumy[n] - sumy[lowy] ) - ( ( n - lowy ) * ( qx - qy ) ) );
  41. ans >>= 1;
  42. printf( "%lld\n", ans );
  43. }
  44. }
  45. return 0;
  46. }

2019计蒜客信息学提高组赛前膜你赛 #2(TooYoung,TooSimple,Sometimes Naive的更多相关文章

  1. 计蒜客 NOIP 提高组模拟竞赛第一试 补记

    计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...

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

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

  3. 计蒜客NOIP2017提高组模拟赛(五)day1-展览

    传送门 发现这题选或不选对状态的优劣程度不会产生影响,如果已经确定了两个数a和b,那么最优的首项和公比也都是唯一确定的, 与对于后面的数x,加进去也好不加进去也好,首项和公比依旧是原来的 于是我们用尺 ...

  4. 计蒜客NOIP2017提高组模拟赛(五)day1-机智的 AmyZhi

    传送门 很水的题目啦QAQ #include<cstdio> #include<cstdlib> #include<algorithm> #include<c ...

  5. 计蒜客NOIP2017提高组模拟赛(五)day2-蚂蚁搬家

    传送门 这题可以用线段树来维护 #include<cstdio> #include<cstdlib> #include<algorithm> #include< ...

  6. 计蒜客NOIP2017提高组模拟赛(五)day2-成绩统计

    传送门 用hash,因为map的复杂度可能在这题中因为多一个log卡掉,但是hash不会 可能因为这个生成的随机数有循环的情况,不是完全均匀的 而且这题hash表的长度也可以开的很大 #include ...

  7. 计蒜客NOIP2017提高组模拟赛(三)day2-数三角形

    传送门 这题有点坑啊 设A为两边颜色不同的角,B为两边颜色相同的角 那么考虑三种三角形:异色,同色,其他 对于任何一个异色三角形,一定会有三个颜色不同的角, 对于任何一个同色三角形,一定会有零个颜色不 ...

  8. 计蒜客NOIP2017提高组模拟赛(三)day2-直线的交点

    传送门 简单几何+逆序对 发现当两条直线甲乙与平板的交点在上面甲在较左的位置,那么下面甲在较右的位置就可以相交 然后把上面的位置排下序,下面离散化+树状数组即可 #include<cstdio& ...

  9. 计蒜客NOIP2017提高组模拟赛(三)day2-小区划分

    传送门 dp,注意边界 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cst ...

随机推荐

  1. G1最佳实践

    示例 -Xms1550m -Xmx1550m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -verbosegc -XX:+PrintGCDateStamps -Xlog ...

  2. spring给予XML配置的声明式事务

    步骤: 1.添加aop.tx命名空间声明: 2.配置事务管理器: 3.配置增强: 4.配置aop 具体xml设置如下: <?xml version="1.0" encodin ...

  3. fiddler模拟返回响应数据

    通过find查找修改指定内容 选择find a file 保存后重新发起请求

  4. 吴裕雄--天生自然 R语言开发学习:导入数据

    2.3.6 导入 SPSS 数据 IBM SPSS数据集可以通过foreign包中的函数read.spss()导入到R中,也可以使用Hmisc 包中的spss.get()函数.函数spss.get() ...

  5. CPU|MICGPU|FPGA|超算|Meta-data|

    生物医学大数据: 收集数据后对数据的分析,如同看相,而对数据信息的挖掘可以看作是算命.这两个过程是基于算法和软件这类工具之上的. 在存储方面:在硬件上,为了Parallel computing的目的, ...

  6. python基础实现简单的shell sed 替换功能

    #coding:utf-8 from pygame.draw import lines import sys,os old_file = sys.argv[1] #接受外部设备上的参数 new_fil ...

  7. Docker快速安装kafka

    Docker快速安装kafka | 沈健的技术博客 盒子 盒子 博客 分类 标签 友链 搜索 文章目录 同样基于docker-compose安装,Docker快速部署nginx中有讲到,不在重述 1. ...

  8. LeetCode~1033.移动石子直到连续

    1033.移动石子直到连续 三枚石子放置在数轴上,位置分别为 a,b,c. 每一回合,我们假设这三枚石子当前分别位于位置 x, y, z 且 x < y < z.从位置 x 或者是位置 z ...

  9. python基础-流程控制语句

    所谓流程控制,就是在程序里面设定一些条件判断语句,满足哪条,就执行哪条 #if 单分支 if 条件: 满足条件后执行的代码 #例子 > : print()#结果为666 双分支 if 条件: 满 ...

  10. Docker深入浅出系列 | Docker Compose多容器实战

    目录 前期准备 Docker Compose是什么 为什么要用Docker Compose Docker Compose使用场景 Docker Compose安装 Compose Yaml文件结构 C ...