jzoj 模拟赛总结(2017.07.14)
来源:互联网 发布:有什么英语翻译软件 编辑:程序博客网 时间:2024/06/06 01:38
T1.
Square :
题目大意:
有一个平面直角坐标系,小D将N个左下角为x1,y1,右上角为x2,y2的方块纸放在这个坐标系中,N个方格纸的都与x轴、y轴平行,Q次查询对于平面直角坐标系中的一个点[x,y]有多少个方格纸覆盖(包括方格纸的边和点)。
30%的数据, N*Q≤10^7。
100%的数据, N,Q≤10^5,0 < x1,y1,x2,y2,x,y≤3000
题解:
30分不难发现,暴力强行枚举判断即可,时间复杂度:O(NQ)
而对于100而言,
其实就是多了一个差分,我们利用差分的思想,每次将输入的x1,y1,x2,y2中
a[x1,y1]+1 a[x2,y2]+1
a[x2+1,y1]-1 a[x1,y2+1]-1
然后我们将上面的做一个前缀和,发现
sum[i,j]=sum[i-1,j]+sum[i,j-1]-sum[i-1,j-1]+a[i,j]
时间复杂度:O(N+Q+max(x2)*max(y2))
var a,sum:array [0..3001,0..3001] of longint; x,y,x1,y1,maxx,maxy,i,j,n,m:longint;function max(aa,bb:longint):longint;begin if aa>bb then exit(aa); exit(bb);end;begin assign(input,'square.in'); reset(input); assign(output,'square.out'); rewrite(output); readln(n); for i:=1 to n do begin readln(x,y,x1,y1); inc(a[x,y]); inc(a[x1+1,y1+1]); dec(a[x1+1,y]); dec(a[x,y1+1]); maxx:=max(maxx,x1); maxy:=max(maxy,y1); end; for i:=1 to maxx do for j:=1 to maxy do sum[i,j]:=sum[i,j-1]+sum[i-1,j]-sum[i-1,j-1]+a[i,j]; readln(m); for i:=1 to m do begin readln(x,y); writeln(sum[x,y]); end; close(input); close(output);end.
T2.
算法学习:
给出N个无序不重复的数,再有M个询问,每次询问一个数是否在那N个数中,若在,则ans增加2^K,K为该数在原数列中的位置。
由于ans过大,所以只要求你输出ans mod 10^9+7。
30% 0 < N,M<100
50% 0 < N,M<10000
100% 0 < N,M<100000
输入的数均在2^31 以内
题解:
排序+离散(或二分):
将其排序后离散,然后开个桶去做,因为离散后最坏情况最大值为200000.
当然也可以排序后二分位置。
时间复杂度:O(N+M)
const modn=1000000007;var rp,d,lxy,num:array [0..200001] of longint; iq:Array [0..100001] of longint; ans,i,j,n,m:longint;procedure qsort(l,r:longint);var i,j,mid:longint;begin if l>=r then exit; i:=l; j:=r; mid:=num[(l+r) div 2]; repeat while num[i]<mid do inc(i); while num[j]>mid do dec(j); if i<=j then begin num[0]:=num[i]; d[0]:=d[i]; num[i]:=num[j]; d[i]:=d[j]; num[j]:=num[0]; d[j]:=d[0]; inc(i); dec(j); end; until i>j; qsort(i,r); qsort(l,j);end;begin assign(input,'sfxx.in'); reset(input); assign(output,'sfxx.out');rewrite(output); readln(n,m); iq[0]:=1; for i:=1 to n do begin read(num[i]); d[i]:=i; iq[i]:=iq[i-1]*2 mod modn; end; iq[0]:=0; readln; for i:=n+1 to n+m do begin read(num[i]); d[i]:=i; end; qsort(1,n+m); i:=1; j:=1; while i<=n+m do begin rp[d[i]]:=j; while num[i]=num[i+1] do begin inc(i); rp[d[i]]:=j; end; inc(i); inc(j); end; for i:=1 to n do lxy[rp[i]]:=i; for i:=n+1 to n+m do ans:=(ans+iq[lxy[rp[i]]]) mod modn; writeln(ans); close(input); close(output);end.
T3.
等飞机:
有一个n列的棋盘,一开始NNS在NNS的这边摆放若干个棋子(摆放的位置由NNS说了算,且有可能n列都不摆棋子),第I列为1表示一开始就放了,不然为0就没放。这个回合算是第1回合,这时候到SG摆放棋子(SG也可以n列都不摆棋子),条件是SG摆放的棋不能和SG上一轮摆的棋矛盾(如下图)。
但是,如果SG只在第四列摆棋子的话,那么就和上一轮的不矛盾。这算是第2回合。
SG继续摆棋,即第3回合。然后SG一直继续摆棋子(接下来在任意的一个回合内,SG也可以n列都不摆棋子),直到第L回合结束。如果这L回合没有出现任何的矛盾情况,则算SG赢。
NNS知道SG肯定赢定了,因为这次NNS不想SG这么伤心,故意让SG的,求SG赢的方案数(对100000007取模)
题解:
状压DP:
设f[i,j]表示第i行状态为j时的方案总数。
然后f[i,j]=Σf[i-1,k]为从上一行种状态为k,不过要注意,我们要判断k时候能转换成j。
然后我们的初值,就是f[1,j]=1
然后推得时候,
i从2 to l
j,k从1 to 1 shl n-1
时间复杂度:O(L*2^2N)
很明显会爆,我们优化它
我们发现对于i-1行的某个状态k,如果j and k=0即,j能由k转换,那么
k=k+1 f[i,j]=f[i,j]+f[i-1,k]
不然的话,我们就可以将k累加上j and k
时间复杂度:O(L*2^N*K)
K大大小于2^N
const modn=100000007;var f:array [0..51,0..8192] of longint; d:array [0..13] of longint; i,j,k,x,n,l,s:longint;begin assign(input,'old.in'); reset(input); assign(output,'old.out');rewrite(output); readln(n,l); d[1]:=1; for i:=2 to n+1 do d[i]:=d[i-1]*2; j:=0; s:=0; for i:=0 to d[n+1]-1 do f[1,i]:=1; for i:=1 to n do begin read(x); if x=1 then s:=s+d[i]; end; for i:=2 to l do begin for j:=0 to d[n+1]-1 do begin k:=0; while k<=d[n+1]-1 do begin if k and j=0 then begin f[i,j]:=(f[i,j]+f[i-1,k]) mod modn; inc(k); end else k:=k+k and j; end; end; end; writeln(f[l,s]); close(input); close(output);end.
T4.
毁灭:
题目大意:
毁灭者们有一堆二向箔和光粒,他们把这些分成了n份,支持毁灭地球和毁灭三体的两拨人各派出一个代表。由支持毁灭地球的代表先执行,接着两个代表分别执行。每次执行可以选择一份二向箔和光粒并将他们全部拿走,直到只剩下m份。如果剩下的二向箔和光粒的总数为偶数个,那么三体文明将会先被消灭,否则地球文明将会先被消灭。
两位代表都会尽全力让自己赢。
如果三体先被毁灭则输出“Three-Body”,否则输出“Earth”
对于30%:n<=10
对于100%:n<=500000,0 < m<=n
二向箔和光粒的个数<=1000000
数据组数不会太多
题解:
找规律:
我们分析发现先手赢的条件是最后的和为奇数,那么后手赢的条件是为偶数
分类去讨论:
①如果双方都不能拿,即N=M,那么直接判断
②如果后手能拿掉所有的奇数,那么后手胜
③如果后手能拿掉所有的偶数,并且用掉剩下的操作次数后,剩下偶数,后手胜
④如果先手能拿掉所有的偶数,并且用掉剩下的操作次数后,剩下奇数,先手胜
最后如果上面都不满足,就代表剩下的总有奇数和偶数,那么判断谁拿了最后一次,谁就能胜。
时间复杂度:O(TN)
var a:array [1..2] of longint; sum,i,j,x,n,m,ans,p,q:longint;begin assign(input,'destroy.in'); reset(input); assign(output,'destroy.out'); rewrite(output); while not(eof) do begin readln(n,m); a[1]:=0; a[2]:=0; for i:=1 to n do begin read(x); if odd(x) then inc(a[1]) else inc(a[2]); end; readln; sum:=a[1]+2*a[2]; if n=m then begin if odd(sum) then writeln('Earth') else writeln('Three-Body'); end else begin p:=0; q:=0; q:=(n-m) div 2; p:=(n-m+1) div 2; if (q>=a[1]) or ((q>=a[2]) and (not(odd(sum-a[2]-p-q)))) then writeln('Three-Body') else if (p>=a[2]) and (odd(sum-a[2]-p-q)) then writeln('Earth') else if p>q then writeln('Earth') else writeln('Three-Body'); end; end; close(input); close(output);end.
- jzoj 模拟赛总结(2017.07.14)
- jzoj 模拟赛总结(2017.07.08)
- jzoj 模拟赛总结(2017.07.09)
- jzoj 模拟赛总结(2017.07.10)
- jzoj 模拟赛总结(2017.07.11)
- jzoj 模拟赛总结(2017.07.12)
- jzoj 模拟赛总结(2017.07.13)
- jzoj 模拟赛总结(2017.07.15)
- jzoj 2016.5.14noip模拟赛C 总结
- [暑假集训] jzoj 2016.7.14 noip模拟赛B 总结
- [暑假集训] jzoj 2016.8.14 noip模拟赛B 总结
- 【集训】jzoj 2017.7.14 noip模拟赛A 总结
- jzoj 2016.11.27 gdkoi模拟赛 总结
- 【集训】jzoj 2017.7.5 noip模拟赛A 总结 (欧拉回路)
- jzoj 2016.5.21noip模拟赛C 总结
- jzoj 2016.5.28noip模拟赛C 总结
- jzoj 2016.6.11noip模拟赛B总结
- jzoj 2016.6.25noip模拟赛C 总结
- 技术大牛养成指南,一篇不鸡汤的成功学实践
- ASP快速、简单连接SQL server
- I.MX6Q(TQIMX6Q/TQE9)学习笔记——U-Boot移植
- ZTree+JAVA写一棵同步树
- 调用微信接口发送消息
- jzoj 模拟赛总结(2017.07.14)
- 为什么心跳包(HeartBeat)是必须的?
- AndroidStudio打包apk,安装失败,提示应用未安装解决
- 单例模式最优方案
- Kotlin 语法的简单介绍
- scala 传名调用call-by-name
- 【社交系统研发日记】如何在 Laravel 中 “规范” 的开发验证码发送功能 !
- CentOS 7 关闭图形界面
- Laravel基础-Illuminate所在位置