2016.8.15
考试思路:
T1
这题比较简单,其实就是模拟选歌和平均分配权值的过程而已,每次找最大权值的一首歌,输出,然后给除了它自己以外的n-1首歌加上r[i] div (n-1),然后判断能不能整除,如果不能则从1到n,除了自己以外,一个一个加上1,每次给其他权值加上1时,dec(除剩的余数),直到余数变为0则退出这个循环。
T2
这题就更简单了,直接从小到大快排然后两个for循环i从1到n-1,j从i+1到n,暴力枚举每一个l[i]+l[j]是否小于等于s,当然还要加上一点优化,就是如果l[i]+l[j]大于s,则l[i]即使再加后面的l[j]也一定不会满足条件,所以退出内循环,每次满足条件答案加一,就可以了。
T3
这题比赛时没想出方法,只是听见别人说可以用弗洛伊德算法,所以一直围绕这个来想,但也没有想出来。
T4
动态规划。f[i,j]表示第i分钟疲劳值为j的最大路程,因为每次休息都必须休息到疲劳值为0,还有结束时疲劳值一定为0,所以可推出状态转移方程,核心代码如下:
- for i:=1 to n do
- begin
- f[i,0]:=f[i-1,0]; //这次的最大值先赋为上次的最大值
- for j:=1 to m do
- begin
- if i>=j then
- f[i,0]:=max(f[i,0],f[i-j,j]); //比较现在的最大值和之前在第j分钟时休息哪个更大
- f[i,j]:=max(f[i-1,j-1]+a[i],f[i,j]); //比较怎么走值最大
- end;
- end;
正确思路:
T1
同上。
T2
同上。
T3
使用弗洛伊德算法,把输入的a和b进行处理,f[a,b]:=a,f[b,a]:=a,表示这a和b的胜者为a,也就是他们两个的父亲,然后和常规的弗洛伊德算法一样,三层循环,中转点k放外面,判断f[i,k]是否等于i,而f[k,j]是否等于k,如果成立,则证明i间接性的击败了j,f[i,j]:=i,f[j,i]:=i,最后判断每一只奶牛的父亲和儿子是否累加起来等于n-1,如果是则累加答案,就可以了。核心代码如下:
- for k:=1 to n do
- for i:=1 to n do
- for j:=1 to n do
- if (i<>j) and (f[i,j]=0) and (f[i,k]=i) and (f[k,j]=k) then
- begin
- f[i,j]:=i;
- f[j,i]:=i;
- end;
- for i:=1 to n do
- begin
- t:=0;
- for j:=1 to n do
- begin
- if f[i,j]<>0 then inc(t);
- end;
- if t=n-1 then inc(ans);
- end;
T4
同上。