2017广东工业大学程序设计竞赛决赛相关总结

这是一直以来,自己碰到的最简单的网络赛

这么说主要是用到的高级数据结构、算法不是很多

除了一些知识盲区,还是在一些基础的问题上翻了船

但是不得不吐槽广工的OJ,前面几个题一个半小时可以出结果,后面的就两个半小时了。。。

以后本校出了OJ后,判题部分一定好好处理,不能贸然办这么大的比赛

VJ还有题,先简单总结一下


题目:

Problem A: 两只老虎

Description

来,我们先来放松下,听听儿歌,一起“唱”。

两只老虎两只老虎,跑得快跑得快。

一只没有耳朵,一只没有尾巴。

真奇怪,真奇怪。

Tmk也觉得很奇怪,因为在他面前突然出现了一群这样的老虎,有的没耳朵,有的没尾巴,不过也有正常的。

现在Tmk告诉你这群老虎的耳朵个数,尾巴条数,以及老虎的腿的数目,问你有多少只是正常的。

其中只有三种老虎:

第一种(正常的):有2个耳朵、1条尾巴、4条腿

第二种(没耳朵):有0个耳朵、1条尾巴、4条腿

第三种(没尾巴):有2个耳朵、0条尾巴、4条腿

Input

第一行一个整数T表示有多少组样例。

接下来每一行一个样例:

包含三个整数abc表示总共有a个耳朵,b条尾巴,c(<=4000)条腿,数据保证有解。

Output

对于每组样例输出一行,表示有多少只正常的老虎。

Sample Input

112 7 40

Sample Output

3

HINT

思路:鸡兔同笼题,推出公式直接出结果

Problem B: 占点游戏

Description

众所周知的是,TMK特别容易迟到,终于在TMK某次又迟到了之后,Maple怒了,Maple大喊一声:“我要跟你决一死战!”然后Maple就跟TMK玩起了一个关于占点的游戏。

Maple在一个无限展开的只有整数点的二维平面上找到两个点,由TMKMaple分别操控这两个点,两人轮流操作,每一次操作中TMKMaple可以把他的点移动一格到上、下、左、右四个方向,当TMK操作时,移动到的这个点会被染成红色,而当Maple操作时,移动到的这个点会被染成蓝色,需要注意的是,两个起始时的两个点也都会被染上相应的颜色,而当任一人走到已经染了不同颜色的点,这个颜色会被覆盖掉,当两个点覆盖在一起时,这个点会被后来的点染色。当游戏结束时染着自己颜色的点就代表被自己占领了。

TMK一下就明白了,这个游戏的目标是让自己占领的点比对方占领的点多,而且要让差值最大。

为了公平一些,Maple决定让TMK来选择先手或后手和让TMK来选择点,相应的Maple就会选择另一个点。

现在给出游戏的总轮数NMaple选择的两个点的坐标(x1y1),(x2y2),要TMK来选择先后手和起始点,假设Maple一定按最优策略来走,问TMK能不能选择先后手和起始点使得自己占领的点比Maple占领的多,如果能,那么同时要求出占领的点数的最大差值。

Input

第一行一个T,代表接下来有T组数据(1<=T<=2000)

每组数据有五个整数N,x1,y1,x2,y2,代表了操作的总轮数N以及选择的两个起始点(x1,y1),(x2,y2),其中1<=N<=10^8-10^8<=x1,y1,x2,y2<=10^8,数据保证两个点不相同。

Output

对于每一组数据,如果TMK占领的点不能比Maple占领的多,那么输出-1,否则输出两个占领点数的最大差值。

Sample Input

41 0 0 1 02 0 0 1 01 0 0 2 02 0 0 2 0

Sample Output

2-11-1

HINT

思路:了解题意后,并没有找到思路



Problem C: 爬楼梯

Description

小时候,我只能一阶一阶得爬楼梯,

后来,我除了能一次爬一阶,还可以一次爬两阶,

到现在,我最多一次可以爬三阶。

那么现在问题来了,我想爬上n层楼,相邻楼层之间有一段楼梯,虽然我一次可以爬1个台阶、2个台阶和3个台阶,但是我在ii+1层之间的楼梯上时,我不能跨越到i+1i+2层之间的楼梯。现在有个n层的楼,知道每一段楼梯的阶数,我想知道,如果我只会往上走,并且忽略其他不在楼梯上的其他移动,共有多少种方案可以到达第n层。

Input

第一行一个整数T0<T<=50)表示有多少组样例。

对于每一组样例:

第一行一个n1<n<=50)表示有多少层楼。

接下来一行,包括n-1个整数xi0<xi<=20),由下到上依次表示每段楼梯的长度。

Output

对于每组数据,输出一行表示共有多少种方案。由于答案较大,所以输出答案请对10007取模。

Sample Input

22344 5 6

Sample Output

42184

HINT

思路:递推。重点是,在不同层数的台阶,有多种可能





Problem D: 只有通过毁灭才能揭示真理

Description

“只有通过毁灭才能揭示真理。” —— 虚空之眼

维克兹是一个有触手的虚空来客,他带着非凡的意图探索着符文之地:吸收掉所有知识。凭借着他不断地注视,维克兹可以发射瓦解光线来灭除并分析他途中的一切东西,并为他供给数量庞大的信息。没人知道他为什么需要如此多的材料,尽管有人推测他设法了解符文之地,是为了加速它的毁灭。

另外,维克兹本身也是一个极其强大的魔法师,他的技能会对命中的敌人施加有机体解构效果。如果累积到3层效果,敌人就会受到爆发性的真实伤害。

现在,维克兹正准备施展他的绝招 —— 生命形态瓦解射线,来对付被永久眩晕且没有携带任何魔抗装备的约德尔人。另外,他的绝招每10秒就可以对敌人累积一层有机体解构效果。

维克兹希望找到能够跟他一起遨游大陆的伙伴,所以他准备考考你,如果已知生命形态瓦解射线持续的时间和每一秒的伤害,以及有机体解构效果每累积到3层所爆发的伤害(伤害爆发后层数归零),你是否能算出约德尔人受到的总伤害是多少呢?

请注意,如果你回答不出来,维克兹绝对很乐意将你一起分解掉。

Input

输入包括T组数据,每组数据包括生命形态瓦解射线的持续时间A,每一秒的伤害B,以及有机体解构效果每累积到3层所爆发的伤害C

T <= 10000, 0 <= A, B, C <= 10000, 所有数据皆为整数)

Output

输出一个数代表约德尔人受到的总伤害。

Sample Input

210 10 1030 10 10

Sample Output

100310

HINT

思路:水题。





Problem E: 倒水(Water)

Description

一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水。接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子。每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里,然后把空瓶丢弃。(不能丢弃有水的瓶子)

显然在某些情况下CC无法达到目标,比如N=3,K=1。此时CC会重新买一些新的瓶子(新瓶子容量无限,开始时有1升水),以到达目标。

现在CC想知道,最少需要买多少新瓶子才能达到目标呢?

Input

第一行一个整数T,表示有T组数据。

接着T每行两个正整数, N,K(1<=N<=10^9K<=1000)

Output

一个非负整数,表示最少需要买多少新瓶子。

Sample Input

33 113 21000000 5

Sample Output

1315808

HINT






Problem F: tmk找三角

Description

有一棵树,树上有只tmk。他在这棵树上生活了很久,对他的构造了如指掌。所以他在树上从来都是走最短路,不会绕路。他还还特别喜欢三角形,所以当他在树上爬来爬去的时候总会在想,如果把刚才爬过的那几根树枝/树干锯下来,能不能从中选三根出来拼成一个三角形呢?

Input

第一行输入一个T,表示有多少组样例。

对于每组数据:第一行包含一个整数 N,表示树上节点的个数(从 1 N 标号)。

接下来的 N-1 行包含三个整数 a, b, len,表示有一根长度为 len 的树枝/树干在节点 a 和节点 b 之间。

接下来一行包含一个整数 M,表示询问数。

接下来M行每行两个整数 S, T,表示毛毛虫从 S 爬行到了 T,询问这段路程中的树枝/树干是否能拼成三角形。

Output

对于每组数据,每个询问输出一行,包含"Yes"“No”,表示是否可以拼成三角形。

Sample Input

251 2 51 3 202 4 304 5 1523 43 551 4 322 3 1003 5 454 5 6021 41 3

Sample Output

NoYesNoYes

HINT


对于20%数据 1 ≤ N, M ≤ 1000


对于所有数据 1 ≤ N ≤ 100000, 1 ≤ M ≤ 100000, 1 ≤ len ≤ 1000000000






Problem G: 等凹数字

Description

定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如5432123455544334455是合法的等凹数字,543212346123321,111111不是等凹数字。现在问你[L,R]中有多少等凹数字呢?

Input

第一行一个整数T,表示数据的组数。

接下来T行每行俩个数字L和R,(1<=L<=R<=1e18)

Output

 输出一个整数,代表[L,R]中有多少等凹数字

Sample Input

21 100101 200

Sample Output

01

HINT

 小于等于2位的数字无凹峰






Problem H: tmk买礼物

Description

今天是校赛的日子,为了庆祝这么喜庆的日子,TMK打算买些礼物给女票LSH庆祝一下。

TMK进入了雪梨超市,然后刚踏入的一瞬间,店主就对TMK说:“恭喜你成为了本店第2147483647位顾客,本店在搞一个活动,对本店第2147483647位顾客进行赠送活动。你先看看你有多少钱?”

TMK一摸口袋,发现只有n个硬币,每个硬币的价值为a[i]

然后店主继续说:“现在你用你的钱凑一些数,如果你的钱能凑成[0,x]里面所有的数,那么你将会免费获得该店价值x元的代金券,假设你有四个硬币面值分别为1,2,4100,你就可以凑成[0,7]里面所有的数,我们将会送你7元的代金券。现在就用你的硬币来试试吧。Enjoy yourself!”

TMK努力凑钱的时候,店主想知道他要送多少代金券给TMK

Input

第一行一个整数T,表示数据组数。

对于每组数据,首先读入一个整数nn<=100000),然后接下来的一行有n个整数,表示a[i] 0<a[i]<=1e9

Output

对于每个数据,输出一个整数x,表示店主要送x元的代金券给TMK

Sample Input

131 2 3

Sample Output

6

HINT

思路:给出数列,判断所有数能拼成的最大面值是多少。开始不知为何联系到母函数,其实思路很简单。。。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#define PI acos(-1.0)
#include<vector>
using namespace std;
long long ans,a[1000005];
int main(){
    int n,T;
    int i,j,k;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(i=0;i<n;i++){
            scanf("%lld",&a[i]);
        }
        sort(a,a+n);
        ans=0;
        for(i=0;i<n;i++){
            if(ans+1>=a[i])
                ans+=a[i];
            else
                break;
        }
        printf("%lld\n",ans);
    }
    return 0;
}















官方题解:

Problem A: 两只老虎
正常的+有耳朵的 = a/2
正常的+有尾巴的 = b
正常的+有耳朵的+有尾巴的 = c/4
正常的 = a/2+b-c/4
Problem B: 占点游戏
d = abs(x1-x2)+abs(y1-y2)
首先判断(n+1)/2 >= d, 先手可不可以从一个点走到另一个点 :
如果不可以, 则先手可以多得 n&1 分(因为劣势者可以选择逃离)
如果可以, 考虑 d 的奇偶性:
如果 d 为奇数(先手可以先踩到后手覆盖过的点) :
如果 n 为奇数, 先手可以多得 2 分, 否则平。
否则( d 为偶数) :
如果 n 为奇数, 先手可以多得 1 分, 否则后手可以多得 1 分。
Problem C: 爬楼梯
先分段考虑:
对于一段 x 阶的楼梯, 方案数 f(x) = f(x-1)+f(x-2)+f(x-3) (其中 x >= 3) f(0)=1 f(1)=1 f(2)
= 2
那么对于爬 n 层楼, 只需要算出每一段的方案数, 然后使用乘法原理乘起来即可。
Problem D: 只有通过毁灭才能揭示真理
可以知道每 30 秒可以可以爆发一次 c 伤害, 每 1 秒造成 b 伤害, 那么答案=a*b+a/30*c
Problem E: 倒水(Water)
对于 n 瓶一升的水, 把他们合并后, 最少需要的瓶子数为 n 的二进制中 1 的个数。 假
n 的二进制中 1 的个数大于 k, 那么我们要找到 1 个大于 n 的数, 且二进制中 1 的个数等
k 的最小的数 m, 那么答案为 m-n
假设 n 二进制中, 最右边的 1 在第 i 位(这里的第几位是从右往左数的, 最右边为第 0
位) , 那么假设你加上一个小于 2^i 的数, 结果二进制中 1 的个数只会增加, 如果加上一个
2^i, 则结果二进制中 1 的个数必定不会增加。 所以只需要一直加上一个 2^i(这里的 i 表示
的是当前水的总体积的二进制中最右边的 1 所在的位置) 直到结果中 1 的个数等于 k 即可。
Problem F: tmk 找三角
假设现在有 n 条线段, 假设 n 条边从小到达排序, 如果这 n 条边中没有三条可以构成
三角形, 那么这 n 条边必须满足关系: A[i] >= A[i-2]+A[i-1], 这里的 A[i]表示第 i 条边的大小。
假设 A[i]尽量取最小 A[i]=A[i-2]+A[i-1], 且 A[1]=A[2]=1, 是不是就是一个斐波那契, 也就
是对于一个 n 条边的集合, 如果不存在三条边能构成一个三角形, 那么最长的边至少为 f[n]
表示斐波那契第 n 项。 而题目 中 A[i]<1e9, 也就是只要 n>50, 就必定存在三条边可以构成一
个三角形, 所以我们只需要暴力加入两点路径上的边(如果大于 50, 直接 Yes) , 然后对这
些边进行排序, 枚举第 i 条边为最长边, 贪心判断 A[i]是否小于 A[i-1]+A[i-2]即可。
Problem G: 等凹数字
dp[i][len][pre][up][down][ispa]代表当前第 i 位, 长度为 len, 上一位是什么, 前面是否递
增过, 前面是否递减过, 当前是否符合回文串的性质, 然后记忆化搜索。
Problem H: tmk 买礼物
首先, 先对 a[i]从小到大排序, 假设对于前 i 个硬币, 我们可以组合成 0~y
①如果 a[i+1]>y+1, 那么从 i+1~n 中任意取硬币, 构成的和都>y+1, 所以必定构造不出
y+1, 于是答案等于 y
②如果 a[i+1]<=y+1, 那么前 i+1 位可以组合成 0~y+a[i+1]
所以只需要对硬币从小到大排序, 然后从第一个硬币枚举到最后一个硬币, 或者中途有
某个数够不出来即可得到答案。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值