JZOJ2017.07.08 C组
来源:互联网 发布:linux常用命令mkdir 编辑:程序博客网 时间:2024/05/23 14:14
T1
题目描述:
小x和小y是好朋友。小y的成绩很差,以至于 GPA(平均绩点)在系内倒数。系内一共有 N 位同学,每位同学有自己的 GPA,以及已修学分数,定义 GPT = GPA ×已修学分数。小x为了帮助小y提高成绩,给小y提了一个要求:新学期的 GPA 要超过系内排名第 K 位的同学。 为了帮助理解,给出一个例子:
现在给出系里面每位同学的 GPT(只有一位小数),以及他们的已修学分。你需要帮助小y把排名 第 K 位的同学的 GPA 求出来。
解题思路:预处理+快排,没什么好说的。。。
代码:
var a:array[-10..100011] of real; i,n,k,y:longint; x:real;procedure qsort(l,r:longint);var mid:real; i,j:longint;begin if l>=r then exit; i:=l; j:=r; mid:=a[(l+r) div 2]; repeat while a[i]>mid do inc(i); while a[j]<mid do dec(j); if i<=j then begin a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0]; inc(i); dec(j); end; until i>j; qsort(l,j); qsort(i,r);end;begin assign(input,'sort.in'); assign(output,'sort.out'); reset(input); rewrite(output); read(n,k); for i:=1 to n do begin read(x,y); a[i]:=x/y; end; qsort(1,n); write(a[k]:0:2); close(input); close(output);end.
T2
题目描述:
小x有很多糖果,分成了 N 堆,排成一列。小x说,如果小y能迅速求出第 L 堆到第 R 堆一 共有多少糖果,就把这些糖果都给他。现在给出每堆糖果的数量,以及每次询问的 L 和 R,你需要帮助小y,把每次询问的结果求出来。 注意,你不需要考虑糖果被小y取走的情况。
解题思路:前缀和
a[i]=a[i-1]+x;
x[i]+…+x[j]=a[j]-a[i-1];
代码:
var a:array[-1..100001] of int64; n,m,x,y,i:longint;begin assign(input,'sum.in'); assign(output,'sum.out'); reset(input); rewrite(output); read(n,m); for i:=1 to n do begin read(x); a[i]:=a[i-1]+x; end; for i:=1 to m do begin read(x,y); writeln(a[y]-a[x-1]); end; close(input); close(output);end.
T3
题目描述:
小x开发了一个奇怪的游戏,这个游戏的是这样的:一个长方形,被分成 N 行 M 列的格子,第 i 行第 j 列的格子记为 (i, j),就是说,左上角的格子是 (1, 1),右下角的格子是 (N, M)。开始的时候,小y在 (1, 1),他需要走到 (N, M)。每一步,小y可以走到正右方或者正下方的一个格子。具体地说,如小y现在在 (x, y),那么他可以走到 (x, y + 1) 或 (x + 1, y)。当然,小y不能走出离开这个长方形。 每个格子有积分,用一个 1~10 的整数表示。经过这个格子,就会获取这个格子的积分(起点和终 点的积分也计算)。通过的方法是:到达 (N, M) 的时候,积分恰好为 P 。 现在给出这个长方形每个格子的积分,你需要帮助小y,求出从起点走到终点,积分为 P 的线路有多少条。
解题思路:
递推
设f[i,j,k]为走到(i,j),积分为k的路线有多少条
递推式为f[i,j,k]=f[i,j,k]+f[i-1,j,k-a[i,j]]+f[i,j-1,k-a[i,j]]
代码:
const mo=1000000007;var f:array[-1..102,-1..102,-1..1502]of longint; a:array[-1..102,-1..102]of longint; n,m,p,i,j,k:longint;begin assign(input,'count.in'); assign(output,'count.out'); reset(input); rewrite(output); read(n,m,p); for i:=1 to n do for j:=1 to m do read(a[i,j]); f[0,1,0]:=1; for i:=1 to n do for j:=1 to m do for k:=a[i,j] to p do f[i,j,k]:=(f[i,j,k]+f[i-1,j,k-a[i,j]]+f[i,j-1,k-a[i,j]]) mod mo; write(f[n,m,p]); close(input); close(output);end.
T4
题目描述:
小x有n个小姊妹(根据典故,我们假设n≤3000)。他每天都喜欢按不同标准给小姊妹们排(da)序(fen)。今天,他突然对小姊妹们的名字产生了兴趣。他觉得小姊妹的魅力和她们的名字有密切联系,于是他觉得所有有相似的名字的小姊妹必须排在一起。 相似是指,名字的开头一个或若干个连续字母相同。 于是,小x定下了如下规则: 在任何以同样的字母序列开头的名字之间,所有名字开头必须是同样的字母序列。 比如,像MARTHA和MARY这两个名字,它们都以MAR开头,所以像MARCO或MARVIN这样的名字可以插入这两个名字中间,而像MAY这样的就不行。 显然,按字典序排序是一个合法的排序方案,但它不是唯一的方案。你的任务就是计算出所有合法的方案数。考虑到答案可能很大,输出答案 mod 1 000 000 007。
解题思路:
DFS+数学+排序+分治
首先,要求出每一个名字的长度,并将其补位
然后从小到大排序名字
设s[i]为i的阶乘,公式:s[i]:=(s[i-1]*i) mod 1000000007
求出来这个然后就开始DFS!!
从第x个名字的第z个字母开始,向后寻找不等于的名字的位置,然后分段,分治(分开处理)
那么第x个名字到第y个名字为一组,递归,再分治(dfs(k,i-1,z+1))
然后将不等于的名字的第z位,向上面那样,找到第一个不等于的位置,再分段
如果没有找到,就将等于的分为一段,再继续寻找(dfs*dfs(k,y,z+1))
每次分了多少段就要乘相应段数的阶乘
(其实这个DFS本质想实现的就是分治)
代码:
const m=1000000007 ;var a:array[-1..3002] of ansistring; s:array[-1..3002] of int64; i,j,max,n:longint;procedure exp;begin s[0]:=1; for i:=1 to 3000 do s[i]:=(s[i-1]*i) mod m;end;procedure qsort(l,r:longint);var i,j:longint; mid:ansistring;begin if l>=r then exit; i:=l; j:=r; mid:=a[(l+r) div 2]; repeat while a[i]>mid do inc(i); while a[j]<mid do dec(j); if i<=j then begin a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0]; inc(i); dec(j); end; until i>j; qsort(l,j); qsort(i,r);end;procedure init;begin readln(n); for i:=1 to n do begin readln(a[i]); if length(a[i])>max then max:=length(a[i]); end; for i:=1 to n do for j:=length(a[i])+1 to max do a[i]:=a[i]+'*';end;function dfs(x,y,z:longint):int64;var t,i,j:longint; c:char;begin if z>max then exit(s[y-x+1]); j:=x; c:=a[x,z]; dfs:=1; t:=1; for i:=x+1 to y do if a[i,z]<>c then begin inc(t); dfs:=(dfs*dfs(j,i-1,z+1))mod m; j:=i; c:=a[i,z]; end; if j<>y then dfs:=(dfs*dfs(j,y,z+1)) mod m; dfs:=(dfs*s[t]) mod m;end;begin assign(input,'ranking.in'); assign(output,'ranking.out'); reset(input); rewrite(output); init; exp; qsort(1,n); write(dfs(1,n,1)); close(input); close(output); end.
阅读全文
1 0
- JZOJ2017.07.08 C组
- JZOJ2017.07.09 C组
- JZOJ2017.07.10 C组
- JZOJ2017.07.11 C组
- JZOJ2017.07.12 C组
- JZOJ2017.08.05 C组
- JZOJ2017.08.06 C组
- JZOJ2017.08.08 C组
- JZOJ2017.08.07 C组
- JZOJ2017.08.10 C组
- JZOJ2017.08.11 C组
- JZOJ2017.08.14 C组
- JZOJ2017.08.15 C组
- JZOJ2017.08.16 C组
- JZOJ2017.08.12 C组
- JZOJ2017.08.14 B组
- JZOJ2017.08.06 B组
- JZOJ2017.08.07 B组
- 网络欺骗攻击【总】
- pandas入门——数据的读取
- 【信息系统开发与管理】第二遍导图
- 机器学习十一 评估指标
- 理解高并发(5).synchronized原理及用法
- JZOJ2017.07.08 C组
- ipython notebook 如何打开.ipynb文件?
- LeetCode Two sum c++
- 八大排序算法之选择排序
- AndroidUiTool.jar中UiTool包源码
- scikit-learn 实战之监督学习 1
- 为什么在cuda中调用__syncthreads()显示未定义标识符
- 理解高并发(6).jvm对内置锁的优化
- Linux常用命令