jzoj 模拟赛总结(2017.07.08)
来源:互联网 发布:北京房价数据库 编辑:程序博客网 时间:2024/06/05 15:50
T1:
题目大意:
定义 GPT = GPA ×已修学分数。给出系里面每位同学的 GPT(只有一位小数),以及他们的已修学分。求排名 第 K 位的同学的 GPA 。
对于 100% 的数据:
1 ≤ K ≤ N ≤ 100000,GPT 小数点后至多 1 位,GPA 至多 4.0。
所有同学的学分都在 [1, 250] 的范围
题解:
因为知道 GPT = GPA ×已修学分数,所以我们可以发现GPA=GPT/已修学分,然后求出以后快排,注意从大到小,最后输出第K大。
时间复杂度:O(n)
var a:Array [0..100001] of real; n,k,i,j:longint; x,y:real;procedure qsort(l,r:longint);var i,j:longint; mid:real;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(i,r); qsort(l,j);end;begin assign(input,'sort.in'); reset(input); assign(output,'sort.out'); rewrite(output); readln(n,k); for i:=1 to n do begin readln(x,y); a[i]:=x/y; end; qsort(1,n); writeln(a[k]:0:2); close(input);close(output);end.
T2:
题目大意:
给出N个数a[i],以及M个区间查询[l,r]即求出a[l]~a[r]的总和Σ。
对于 50% 的数据:1 ≤ N, M ≤ 100。
对于 100% 的数据:1 ≤ N,M ≤ 100000,0 ≤ Ai ≤ 10000,1 ≤ Li ≤ Ri ≤ N。
题解:
不难发现用前缀和O(N)随便搞搞,然后O(1)求解。
时间复杂度:O(N*M)
var sum:array [0..1000001] of longint; l,r,i,n,m:longint;begin assign(input,'sum.in'); reset(input); assign(output,'sum.out'); rewrite(output); readln(n,m); for i:=1 to n do begin read(sum[i]); sum[i]:=sum[i]+sum[i-1]; end; readln; for i:=1 to m do begin readln(l,r); writeln(sum[r]-sum[l-1]); end; close(input); close(output);end.
T3:
递推:
求从(1,1)走到(N,M)积分为P的方案,每次只能向下或者向右走,每个点的积分为1~10的整数a[i,j],起点跟终点的积分也算。
递推式为f[i,j,k]=f[i,j,k]+f[i-1,j,k-a[i,j]]+f[i,j-1,k-a[i,j]]
初值:
f[i,1,Σa[i,1]]=1
f[1,i,Σa[1,i]]=1
相信大家会有一种错误的感觉,P最大是N*m*10即100*100*10,然后就P=100000,数组开到100*100*10000,费内存,浪费时间。
实则我们自己推理可以发现,到每个点(i,j),只需要走(i-1)+(j-1)步,则(N,M)最大为(100,100)时,P最大为10*((100-1)+(100-1)),而远远没有100*100*10,这时我们就可以将数组的P开成2000。
当然大家如果觉得不够优美可以将N滚动滚动。
时间复杂度:O(NMP)
var f:Array [0..101,0..101,0..2001] of longint; a:array [0..101,0..101] of longint; k,i,j,n,m,p:longint;begin assign(input,'count.in'); reset(input); assign(output,'count.out');rewrite(output); readln(n,m,p); for i:=1 to n do begin for j:=1 to m do read(a[i,j]); readln; end; j:=0; for i:=1 to m do begin j:=j+a[1,i]; f[1,i,j]:=1; end; j:=0; for i:=1 to n do begin j:=j+a[i,1]; f[i,1,j]:=1; end; for i:=2 to n do for j:=2 to m do for k:=0 to p-a[i,j] do f[i,j,k+a[i,j]]:=(f[i-1,j,k]+f[i,j-1,k]) mod 1000000007; writeln(f[n,m,p]); close(input);close(output);end.
T4:
题目大意:
小x有n个小姊妹(根据典故,我们假设n≤3000)。每个小姊妹有自己的名字,他觉得小姊妹的魅力和她们的名字有密切联系,于是他觉得所有有相似的名字的小姊妹必须排在一起。
相似是指,名字的开头一个或若干个连续字母相同。
于是,小x定下了如下规则:
在任何以同样的字母序列开头的名字之间,所有名字开头必须是同样的字母序列。
比如,像MARTHA和MARY这两个名字,它们都以MAR开头,所以像MARCO或MARVIN这样的名字可以插入这两个名字中间,而像MAY这样的就不行。
显然,按字典序排序是一个合法的排序方案,但它不是唯一的方案。你的任务就是计算出所有合法的方案数。考虑到答案可能很大,输出答案 mod 1 000 000 007。
对于60%的数据:3 ≤ n ≤ 10。
对于100%的数据:
3 ≤ n ≤ 3000
1 ≤ 字符串长度 ≤ 3000,并且只含有大写字母。
题解:
DFS+数学+排序+分治
先找出名字的最大长度,然后每个根据这个补位
然后按字典序排序名字
设f[i]为i个数的排列方案 那么f[i]=i!
递推式:
f[0]:=1
f[i]:=f[i-1]*i
//题目数据大,要注意取模以及开int64 / long long
然后dfs分治
从第dep个字母开始,向后寻找不等于的名字的位置,然后分段处理
//初始dep=1
如果第dep位的字母,第l个到第r个名字相同则分为1组,递归分治
dfs:=dfs*dfs(dep+1,l,r)
直到N个名字的第dep位都分到自己的“段”
//每个dfs初始=1
若每次分了gd段,则dfs=dfs*f[gd]
因为分了gd段,我们就看成gd个整体,即gd个不同的数去处理,因为字母相同,所以可以打乱顺序,则要*排列方案f[gd]
const modn=1000000007;var k:array [0..3001] of ansistring; f:array [0..3001] of int64; i,j,n,m,maxl:longint;function dfs(dep,l,r:longint):int64;var i,j,gd:longint;begin if l=r then exit(1); if dep>maxl then exit(f[r-l+1]); dfs:=1; j:=l; gd:=1; for i:=l to r do if k[i][dep]<>k[j][dep] then begin inc(gd); dfs:=dfs*dfs(dep+1,j,i-1) mod modn; j:=i; end; if k[r][dep]=k[j][dep] then dfs:=dfs*dfs(dep+1,j,r) mod modn; dfs:=dfs*f[gd] mod modn; exit(dfs);end;procedure qsort(l,r:longint);var i,j:longint; mid:ansistring;begin if l>=r then exit; i:=l; j:=r; mid:=k[(l+r) div 2]; repeat while k[i]<mid do inc(i); while k[j]>mid do dec(j); if i<=j then begin k[0]:=k[i]; k[i]:=k[j]; k[j]:=k[0]; inc(i); dec(j); end; until i>j; qsort(i,r); qsort(l,j);end;begin assign(input,'ranking.in'); reset(input); assign(output,'ranking.out');rewrite(output); readln(n); f[0]:=1; for i:=1 to n do begin readln(k[i]); if length(k[i])>maxl then maxl:=length(k[i]); end; for i:=1 to 3000 do f[i]:=(f[i-1]*i) mod modn; for i:=1 to n do for j:=1 to maxl-length(k[i]) do k[i]:=k[i]+'0'; qsort(1,n); writeln(dfs(1,1,n)); close(input); close(output);end.
- jzoj 模拟赛总结(2017.07.08)
- jzoj 模拟赛总结(2017.07.09)
- jzoj 模拟赛总结(2017.07.10)
- jzoj 模拟赛总结(2017.07.11)
- jzoj 模拟赛总结(2017.07.12)
- jzoj 模拟赛总结(2017.07.14)
- jzoj 模拟赛总结(2017.07.13)
- jzoj 模拟赛总结(2017.07.15)
- jzoj 2016.11.27 gdkoi模拟赛 总结
- jzoj 2017.10.08 模拟赛
- 【集训】jzoj 2017.7.5 noip模拟赛A 总结 (欧拉回路)
- jzoj 2016.5.14noip模拟赛C 总结
- jzoj 2016.5.21noip模拟赛C 总结
- jzoj 2016.5.28noip模拟赛C 总结
- jzoj 2016.6.11noip模拟赛B总结
- jzoj 2016.6.25noip模拟赛C 总结
- [暑假集训] jzoj 2016.7.7 noip模拟赛C 总结
- [暑假集训] jzoj 2016.7.8 noip模拟赛C 总结
- 【知识库】--Dubbo ReferenceBean获取 -- 源码过程(254)
- LINUX2.6输入子系统设备模型分析
- INPUT设备输入事件的传递过程
- bootstrap-datepicker日历插件 与bootstrapValidator验证同时使用时无效
- Escape HDU
- jzoj 模拟赛总结(2017.07.08)
- 第六天,晚了
- CodeVS 3344 迷宫 题解
- 洛谷P3379 【模板】最近公共祖先(LCA)
- 9Patch图片
- HTML+CSS编写静态网站-30 课后作业06
- 服务器上下拉风格展现异常,无法点击问题解决方案
- bzoj 4776: [Usaco2017 Open]Modern Art 二维差分
- [7.7] 纪中C组