vijos.docx
- 文档编号:8111642
- 上传时间:2023-01-28
- 格式:DOCX
- 页数:19
- 大小:28.73KB
vijos.docx
《vijos.docx》由会员分享,可在线阅读,更多相关《vijos.docx(19页珍藏版)》请在冰豆网上搜索。
vijos
p1000:
直接读入,输出
p1001:
noip原题
p1002:
noip原题
p1003:
noip原题
p1004:
从后面往前面推。
如果win[a,b,c]=true;
可以推出:
win[a,b-1,c]=true;和win[a,b,c-1]=true;
注意b=1和c=1还有b=1andc=1的情况。
p1005:
from:
枚举S1的“分段方式”。
例如231241,如果分段方式为23|124|1,则124为完整的一段,前面必为123,后面必为125,经检验这是可行的。
因此如果有一个完整段的情况可以用O(n^2)次枚举来判定。
剩下只需要解决没有完整段的情况,即被分成两段。
如2312,如果被分为2|312,则需要枚举位数。
如果是3位,有方程?
?
2+1=312,无解;如果是4位,有方程?
?
?
2+1=312?
,有解3122+1=3123。
基本思想如此,但是需要注意有进位的情况。
p1006:
最左边和最右边的点有点特殊。
最好是从下面向上面处理。
那么每个点都有两条路出去。
p1007:
如果圆柱的半径是0,很容易求出答案,再加上2*pi*r。
p1008:
noip原题
p1009:
很容易转化成另一个的问题
一个人在原点,他的速度为v,另一个人在位置b,速度为0,总长为n
求最小的x使得vxmodn=bmodn
就是要求vx+ny=b
可以求出vx+n*y=gcd(x,n)中的x,y用下面的方法求
两边乘以b/gcd(x,n)得到
记c=b/gcd(x,n);
v*(c*x)+n*(c*y)=b;
那么c*x和c*y就是答案
可以用下面的算法求出
这个算法是用来算出ax+by=gcd(a,b)中的整数x,y;
Var{Author:
tangyouze}
x,y,t,a,b,c,d,i,j,n:
int64;
functiongcd(a,b:
int64):
int64;
begin
if(b=0)then
begin
x:
=1;
y:
=0;
exit(a);
end;
gcd:
=gcd(b,amodb);
t:
=x;
x:
=y;
y:
=t-(adivb)*y;
end;
begin
readln(a,b,c,d,n);
b:
=(b+n*1000-a)modn;
a:
=(c+n*1000-d)modn;
d:
=gcd(a,n);
ifbmodd=0then
begin
a:
=x*(bdivd);
while(a<0)doa:
=a+10*n;
b:
=ndivd;
a:
=a-(adivb)*b;
writeln(a);
end
elsewriteln('Impossible');
end.
p1010:
计算a^b,直接算,不会tle,注意输出格式
p1011:
先把所有的点从大到小排序
记录g[i,j]为从以(i,j)结束的最长路的长度
for每个点(从大到小)do
ifg[i,j] ifg[i,j] ifg[i,j] ifg[i,j] 输出最大的g[i,j] p1012: 原来是一道很烦的题目,用分治, 可以按横坐标排序,然后枚举 加一个很强但很简单的剪枝。 但是数据的绝对值稍大,考虑不要用longint fori=1tondo forj=1tondo begin if(x[j]-x[i]>当前的最小值)break; end; p1013: 简单的题目,用动态规划的思想。 可以用叉积来判断直线相交,也可以用解析几何来做。 p1014: 假设有两个人,同时向右走,这两个人不会走过同样的点(起点,终点除外),而且要走过所有的点。 先按x排序 设a[i][j]是一个人走到点i,另一个人走到点j,走过的最短路。 X1=min(a[i][k]+distance[k][j])(k X2=min(a[k][j]+distance[k][i])(k A[i][j]=min(x1,x2); P1015: 对于每一个顶点,如果正面有一条边经过它,那么就把它的权就加1 如果背面有一条边经过它,那么就把它的权就减1; 再搜索连通分量。 对于每一个连通分量,计算所有点的权的绝对值的和除以2 即: q[k]=sum(abs(权(k)))/2;ifq[k]=0thenq[k]=1 再求sum(q[k])既是答案 p1016: 强行搜索即可o(4^9)=262144,每一个操作最多只要改变三次(4个状态), p1017: 字符串处理; p1018: UAC p1019: UAC p1020: UAC p1021: 贪心,如果存在一个人,能和他交流的人 直到结束(满足条件),输出剩下的人数。 那种错误的不用数组的方法竟然也能全过,迷茫中。 P1022: 用o(n*n*n)的传递闭包就行了。 和floyd差不多 fork: =1tondo fori: =1tondo forj: =1tondo a[i][j]=a[i][j]or(a[i][k]anda[k][j]) 然后,对于任意互相可达的两点(a[i][j]anda[j][i]=true) 把这两点收缩成一点。 最后输出剩下的点数 p1023: 先做一个传递闭包 然后搜索强连通分量,最后输出没有入度的点的数目。 P1024: 怎么做都行,大概只要十几步就循环了。 p1025: 最基本的背包 p1026: 宽搜,用hash判重 p1027: UAC p1028: 用o(n^2)的就行,但是,用栈可以优化到o(n),按顺序入栈, forI: =1tondo begin while要进入的字符串不是栈顶字符串的后缀do 出栈 s[i]入栈 end 输出这个栈曾经达到的最大深度 p1029: 似乎只要宽搜,用hash判重就行了,当时没有VividPuppy有一个点是cheat过的,现在又交了一次,AC了 p1030: 直接搜,可以把所有答案枚举出来,再排序,没必要在搜索顺序上下功夫。 P1031: UAC Usaco的题目,有兴趣的可以自己去找,记得他的标程跑的相当快,当然,代码也很长(400行) P1032: Noip原题 P1033: 分出来的数中,3越多越好。 用高精度。 P1034: 最基本的并查集。 P1035: 简单题,注意看清题目。 P1036: 首先,x轴和y轴是无关的。 下面,单独考虑x轴 记录每个城市的权为人口×城市的网络需求程度 下面转换一下: 1个权为k的城市可以看做k个权为1的城市 这样所有的城市的权都是1,下面只要找出最中间的城市就行了。 先快排,再扫一次就行了。 P1037: 是一个选择状态的题目; 状态: g[i,j]表示前i个木块,两塔差距为j时矮的塔最最小的高度 p1038: 动态规划,输出有些麻烦。 如果输入是n=1我不知道输出什么,反正没有这样的数据; 有的时候程序会有多个解 比如输入 22222 输出可以是 (((2+2))+(2+2)+2) 也可以是 ((2+2)+((2+2)+2)) 而数据给的是第二种,体现在No.2和No.8上 关于最后一行, 先把最外面那个加号提出来。 做左边,做右边。 先做: (2+2) 再做: ((2+2)+2)。 。 。 p1039: 当年c++评测有问题,我交了接近80次,最后还是没有ac,强行写成pascal痛苦啊。 。 。 贪心法,组成a,b两个数字(a>b) 如果n是偶数, 先选好最前面的两个数字, a的第一位是第二小的数字(0不算) b的第一位是最小的数字(0不算) 然后,把最小的ndiv2-1个数字放在a的后面 把最大的ndiv2-1个数字放在b的后面 这样a,b差的最小。 如果n是奇数 a的第一位是最小的数字(0不算) b的第一位是最大的数字 然后,把最小的ndiv2个数字放在a的后面 把最大的ndiv2-1个数字放在b的后面 p1040: 用高精度乘法(废话),用longint储存4位,这样就会好多。 P1041: 人数从小到大枚举 p1042: 直接搜索,搜索前面一半,后面一半从前面推,判断是否是素数。 O(sqrt(n)) p1043: 题目没有了。 。 p1044: UAC p1045: 最小生成树,用kruscal+并差集,因为边少 p1046: fork: =1tondo begin fori: =1tondo forj: =i+1tondo if(b[i][j]+a[i][k]+a[k][j] min=b[i][j]+a[i][k]+a[k][j]; fori: =1tondo forj: =i+1tondo if(b[i][k]+b[k][j] b[i][j]=b[i][k]+b[k][j]; End; 修改的floyd算法o(n*n*n)求无向图的最小圈 输出min; P1047: 考验人耐心的题目,慢慢写吧 求出gcd(a,b)输出a*b/gcd(a,b);可以不用高精度除法, P1048: UAC P1049: UAC P1050: UAC P1051: 很多算法都行: floodfill,dfs,并查集。 。 P1052: 高斯消元法。 最后输出的时候可能存在问题,输出round(ans)似乎好一些 ForI: =1tondo Begin Bo: =false; Forj: =1tomdo Begin If(min[edge[j].y]>min[edge[j].x]+edge[j].data)then Begin min[edge[j].y]=min[edge[j].x]+edge[j].data; bo=true; End; End; Ifbo=falsethenbreak; End; Ifbo=truethen有回路 P1053: Bellmanford单源最短路径 有两点要注意的: 1: 可能有自环 2: 注意这样的数据 321 23–1 32–1 这个数据输出的是 -1 而不是 0 NoPath NoPath p1054: wc2002 p1055: wc2002 p1056: 离散化。 然后直接涂色 p1057: 动态规划,a[i][j]表示从以i,j为右下角的时候最大的正方形边长。 如果i,j这个格子上是0那么a[i][j]=0; 否则a[i][j]=max{a[i][j-1],a[i-1][j],a[i-1][j-1]}+1 输出最大的a[i][j]; p1058: 倒推法就是看一下最前面几个数字是从哪里来的 最后看一下,1,2,3,4,5,6,7,8,9,10在那些位置 p1059: 简单的背包,看起来复杂度很高,但不用担心超时。 P1060: 输出: C(n+a,a)*C(n+b,b); P1061: 动态规划: 摘自一大牛语录: 首先将筷子长度从短到长排序。 F[i,j,0]表示i个人使用前j双筷子,且第j根筷子不用,所需要长度差的平方和的最小值。 F[i,j,1]表示i个人使用前j双筷子,且使用第j根筷子,所需要长度差的平方和的最小值。 则 F[i,j,0]=min{f[i,j-1,1],f[i,j-1,0]} F[i,j,1]=F[i-1,j-1,0]+(l[j]-l[j-1])^2 ans=min{F[k,n,1],F[k,n,0]} p1062: o(n*n),似乎要把数组开大一点。 P1063: 可能会认为这样是一个三角形 但实际上不是 注意这种情况,放心的动态规划吧,似乎n<100也是有错的。 P1064: 样例过了应该就不会有什么问题吧 p1065: 当然强行搜索是不行的, 用一点数论的只是就可以解决问题, 首先,想一下如果是强行搜索: 拿样例来说: 1-7-10-11-17-70-71-77-100-107-110。 。 。 运用一点同余的技巧。 比如说 5 mod22=5; 27mod22=5; 那么 (5*10+x)mod22=(27*10+x)mod22 那么,如果在我们搜索的过程中遇到 5后遇到了 22那么这个 22一定不是最优解的前缀, 如果是的话,那么把22换成5一样是一个解,这个解一定比22开头的那个好 即22xxxxx是一个解可以知道5xxxxx也是一个解 比如样例 搜索过程变为: 1-7-10-11-17-70-71-77-100-107-110。 。 。 每个数 mod22 1-7-10-11-17-4-5-11-12-19-0。 。 。 这样,我们的搜索量就大大减小了, hash判重 最后,搜索到0的时候就结束 p1066: 朴素算法 p1067: vijos1067 矩阵乘法 答案等于 |110000| |101000| |100100| |100010| |100001| |100000| 。 。 。 。 。 输出这个矩阵的n次方的左上角第一个格子例的数字mod7777777 运算的时候用int64; a^n快速运算法: 举例子 a^13=1*a^8+1*a^4+0*a^2+1*a^1; 红色的都是2的倍数,得到所有a^1,a^2,a^4...只要O(logn)接下来把他们加起来即可 矩阵的运算也类似 p1068: 看样例: 移动的步数是2^n-1; 下面看数字3, start表示初始的柱子 end表示结束的柱子 如果3在start,那么说明是前4次移动 接下来的任务就是1,2号盘子从1移动到3,就是说sta: =1;end: =3; 如果3在end,那么说明是后4次移动 inc(ans,4); 接下来的任务是1,2号盘子从3移动到2就是说start: =3;end: =1; 如果3在6-start-end,打出-1halt forI: =ndownto1do { if(a[i]=6-sta-end)then { writeln(-1); halt; } if(a[i]=sta)then end=6-sta-end else { sta=6-end-sta; inc(ans,1shl(i-1)); } } P1069: 不知道题目是什么意思,似乎就是p1007上r=0的特例, p1070: 删边,再做最小生成树,用kruscal做最小生成树 p1071: 动态规划 永恒の灵魂提供的数据 4 3 2 3 1 也许会错哦 p1072: 输出: l*2/3/v即可,不用高精度 p1073: http: //purety.jp/akisame/oi/TJU/vol1.htm#1034 p1074: UAC cheat,还有什么方法呢? P1075: 我用树状数组写的 以前ac的程序,现在不能ac了whathappens? http: //www.oibh.org/bbs/attachment.php? aid=4782 p1076: bfs搜索出每个连通分量,看它是不是一条船(长方形) p1077: 先做出前100位,很容易发现规律; a[0]: =2;b[0]: =1;c[0]: =1;d[0]: =0; fori: =1to100do begin a[i]: =(b[i-1]+c[i-1]+2*a[i-1])mod100; b[i]: =(2*b[i-1]+a[i-1]+d[i-1])mod100; c[i]: =(2*c[i-1]+a[i-1]+d[i-1])mod100; d[i]: =(2*d[i-1]+b[i-1]+c[i-1])mod100; end; 答案是以20为循环的 注意,输出的是最后两位 输入 11 输出 00而不是0 p1078: 简单的模拟 p1079: Huffman树 Hint是错的 应该是A—0B-10C-110D-111 似乎这样的输入要特殊处理 AAAAAAA(就是只有一个字母) 其实题目有点问题 如果输入是 BCDEA 朴素编码 a-000;b-001;c-01;d-10,e-11 编码后变成 001’01’10’11’000 如果编码成 a-00;b-001;c-01;d-10,e-11 编码后变成 001’01’10’11’00 bcdea 虽然在前面可以不按照上面的方法来解码,但是到最后面是解不出来的 00’10’11’01’100 adec? 100怎么分解呢? 所以说新的那种编码方法是可行的(不会产生歧义) p1080: 记忆化搜索,没什么难度 数好空格 p1081: UAC p1082: UAC p1083: UAC p1084: 和p1068差不多,就是不会输出-1的,显然要用高精度 p1085: 两个剪枝: 1: 当你最前面确定下来以后,后面不管怎么放,都会小于一个最大值,大于一个最小值, 而如果要求的数不在这个范围里面的时候,剪枝。 样例 416 搜索 1。 。 。 后面最大值是 1*1+3*3+4*3+2*3>16 最小值是 1*1+2*3+3*3+4*1>16 所以第一个数不可能是1 注意,求最大最小值的时候,不要排序,如果要排,也不要用快排,这时还是选择排序快 2: 假设再没有第一个剪枝的情况下(这样讲比较清楚) 当我们搜索到 1234发现没有解 那我们搜索到 132。 。 的时候,马上可以判断没有解 因为在第二个位置和第三个位置的权是一样的,所以后面怎么放都是没有解的。 所以说,在权值一样的地方,如果后面的数字比前面的小,那么剪枝。 这两的剪枝应该就够了。 最快的VividPuppy上差不多1000ms p1086: UAC p1087: 摘自kuye.Oibh: 这是一个相当麻烦的题目。 首先,若要第i个选手“击败”第j个选手,可以列出不等式: L1/(v1i)+L2/(v2i)+L3/(v3i) 显然我们可以通过换元的方法把L3消去。 这样,我们就可以得到形如a*L1+b*L2+c<0(>0)的不等式。 而我们要判断i是否可以取胜,必须解出所有n-1个上面说到的不等式,求出其交集。 注意到这个不等式的几何意义是一个半平面,仅此求交集实际上就是用这些不等式代表的直线去“切割”一个平面(第一象限平面),如果平面被“切没了”,那么说明不等式组的解集为空,第i个选手不可能获胜。 否则第i个选手就可以获胜。 我自己的方法: 9 xyz 1026 1073 567 327 626 357 846 1042 187 先把所有的数都取倒数,这样做起来方便 对于每一个i,要求有没有a,b,c
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- vijos
![提示](https://static.bdocx.com/images/bang_tan.gif)