计蒜客\(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.上下界处理问题:

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

请恰代码:

#include<bits/stdc++.h>
using namespace std;
#define rint register int
int n, MIN;
long long sum, w[510], v[510], dp[250010], ans = ( 1ll << 60ll );
inline int read( void ){
int re = 0, f = 1; char ch = getchar();
while( ch > '9' || ch < '0' ){
if( ch == '-' ) f = -1;
ch = getchar();
}
while( ch >= '0' && ch <= '9' ){
re = re * 10 + ch - '0';
ch = getchar();
}
return re * f;
}
int main( void ){
n = read();
for( rint i = 1; i <= n; i++ ){
w[i] = read(); v[i] = read();
double p; scanf( "%lf", &p );
w[i] *= ( int )( 100.0 * ( 1.0 * ( 1.0 - p ) ) + 0.1 );
sum += w[i];
}
MIN = read(); MIN *= 100;
for( rint i = 1; i <= sum; i++ ) dp[i] = ( 1ll << 60ll );
sum = 0; int j = 0;
for( rint i = 1; i <= n; i++ ){
for( sum += w[i], j = sum; j >= w[i]; j-- ){
dp[j] = min( dp[j], dp[j - w[i]] + v[i] );
}
}
for( rint i = MIN; i <= sum; i++ ){
ans = min( ans, dp[i] );
}
printf( "%lld", ans );
return 0;
}

\(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\)了……

#include<bits/stdc++.h>
using namespace std;
#define rint register int
#define ll long long
int n, q, T;
ll x[1000010], y[1000010], sumx[1000010], sumy[1000010];
ll ans;
inline int read( void ){
int re = 0, f = 1; char ch = getchar();
while( ch > '9' || ch < '0' ){
if( ch == '-' ) f = -1;
ch = getchar();
}
while( ch >= '0' && ch <= '9' ){
re = re * 10 + ch - '0';
ch = getchar();
}
return re * f;
}
int main( void ){
T = read();
while( T-- ){
n = read(); q = read();
for( rint i = 1; i <= n; i++ ){
int t1, t2;
t1 = read(); t2 = read();
x[i] = t1 + t2; y[i] = t1 - t2;
}
sort( x + 1, x + 1 + n ); sort( y + 1, y + 1 + n );
for( rint i = 1; i <= n; i++ ){
sumx[i] = sumx[i - 1] + x[i]; sumy[i] = sumy[i - 1] + y[i];
}
for( rint i = 1; i <= q; i++ ){
ans = 0;
ll qx, qy; qx = read(); qy = read();
ll lowx, lowy;
lowx = upper_bound( x + 1, x + 1 + n, qx + qy ) - x - 1;
lowy = upper_bound( y + 1, y + 1 + n, qx - qy ) - y - 1;
ans += ( ( ( lowx * ( qx + qy ) ) - sumx[lowx] ) + ( sumx[n] - sumx[lowx] ) - ( ( n - lowx ) * ( qx + qy ) ) );
ans += ( ( ( lowy * ( qx - qy ) ) - sumy[lowy] ) + ( sumy[n] - sumy[lowy] ) - ( ( n - lowy ) * ( qx - qy ) ) );
ans >>= 1;
printf( "%lld\n", ans );
}
}
return 0;
}

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. UFT基本操作

    1.打开界面F6快捷录制 2.选择web或者C/S架构软件 3.以C/S为例,点击添加找到相应的地址 4.点击左键添加断点 5.切换视图,初级模式或者代码模式 6.新增步骤 7.点击“手指”图标获取元 ...

  2. Docker 安装 CentOS

    Docker 安装 CentOS CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise ...

  3. cashier|gasoline|reservoir

    N-COUNT 出纳(员);收银员A cashier is a person who customers pay money to or get money from in places such a ...

  4. 翻转链表和k个一组翻转以及两两反转

    一.输入一个链表,输出反转后的链表. 非递归实现: # -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.v ...

  5. [LC] 490. The Maze

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  6. 18.09.22模拟赛T2 历史

    网上基本上找不到这道题,何况LJJ还稍微改了一下...... 原题:传送门 题目描述 ljj 被S 国数不清的漂亮小姐姐所吸引,为了搞清楚为什么S 国有如此多的漂亮小姐姐,他决定研究S 国的历史. 根 ...

  7. 吴裕雄--天生自然KITTEN编程:演唱会

  8. HashMap的四种遍历!

    HashMap的四种遍历 import java.util.Collection; import java.util.HashMap; import java.util.Map; import jav ...

  9. 831. KMP字符串

    给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字. 模板串P在模式串S中多次作为子串出现. 求出模板串P在模式串S中所有出现的位置的起始下标. 输入格式 第一行输入整 ...

  10. Mybatis分页插件的使用流程

    如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件.该插件支持任何复杂的单表.多表分页. 1.引入PageHelper的jar包 在pom.xml中添加如下依赖: 12345 ...