2015-8-7 ACM 模拟赛制测试总结
2016-02-15 19:35
267 查看
这次老师给我们展开了一次ACM赛制的测试,只不过题目少很多,每组的人数也多一些,不过那些题都还蛮难的。我们小组做了三题,和其他组几乎一样,也就是那些水题吧~不过有一些人做了一些难题但却没有做水题,正所谓有得必有失吧。
这次的题目出自USACO,下面是解题报告:
地理 geo
Time Limit:10000MS Memory Limit:65536K
Total Submit:26 Accepted:15
Description
奶牛们刚学习完地理课,知道地球是个球。他们非常震惊,满脑子都是球形。他们试图把地球表面看成一个NxN (1 <= N <= 100)的方格,但是顶端连接着底部、左边连接到右边。格子用坐标表示,左下角坐标为(1,1)。
例如: N=5时,牛从(1,3)位置向下走会到(5,3);从(2,5)向右走会到(2,1)位置。牛可以上、下、左、右和斜线方向走。
如果按照牛的模型,请计算依次行走 M(1 <= M <= 100) 格子的最短路径。
输入格式(file geo.in):
第一行:两个整数: N M。
下面M行:表示依次要行走的格子坐标:r c。
输出格式(file geo.out):
最少行走步数。
输入样例:
5 3
1 1
5 5
3 5
输出样例:
3
说明:先花一步从(1,1)走到(5,5),再花两步从(5,5)走到(3,5)。
这道题很简单主要的解题方法就是宽度优先搜索(或广度优先搜索),但是却有另外一个更好的方法,速度大大提高。
这真是一种聪明的作法!所花费的时间非常短,因为不需要那些广搜的复杂操作,只需计算即可。这个方法好像是由苏畅想出来的。
这种方法还可以解决另一道题:一个球从一个桌子的一角弹出,若它能一直弹下去,并给出初始其所经过的一些格子,问在第N次后这个球刚刚经过哪条边(刚刚经过的意思是指,还没有经过到下一条边)?这道题给出了轨迹,接下来的一些模拟也很简单了。具体的解法请看下面这张图:
单位 unit
Time Limit:10000MS Memory Limit:65536K
Total Submit:31 Accepted:7
Description
某星球上有很多计量系统,之间的计量单位的转换很繁琐。希望你能编程解决这个问题。
现有N (1 <= N <= 100) 个转换关系(比如:12 A 等于 1 B, 3 B等于 1 C等等 ),请计算指定的M (1 <= M <= 100) 个转换关系(比如:多少 A 等于 1 C).
输入格式( unit.in )
第一行:两个整数 N 和 M。
下面N行:每行有3个值:A S1 S2,A是一个小数,S1、S2是两个单词,它们之间用空格分开。表示 A 个 S1 等于 1个S2.
再后面有M行:每行两个单词 X Y,中间用空格分开,请你计算出1个Y相当于多少X。
输出格式 (file unit.out):
共M行:每行对应一个输入数据中的单位转换问题。答案为乘1000之后的四舍五入取整。保证答案不超过2^31.
样例输入:
4 1
12 inch foot
3 foot yard
5280 foot mile
0.0254 meter inch
meter mile
样例输出:
1609344
这题仍然可以用广搜做。把那些转换的信息抽象成一个图中的链接,再用广搜一下子就好了。但是我觉得这个问题要求效率的话应该用像Dijkstra之类的多源最短路径算法,这样显然就能快很多。特别是在以后一些同样是单位转换,但走两条路得到的数量可能有所不同的情况下,最短路径显然改一下就好了。举个例子,假设美元汇人民币为1:6,人民币汇澳门币为1:2,而美元直接汇澳币为1:11,则这种情况下显然是先汇人民币再汇澳币划算。
问题 nroots
Time Limit:10000MS Memory Limit:65536K
Total Submit:31 Accepted:6
Description
一些牛在花园中工作---让他们考虑根,根的乘方是很容易.那些牛是考虑很大的根.
给整数 N(1<=N<=10^25) and K (3<=K<=10)计算整数B,N=B^K;
问题名:nroots
输入文件:
第一行:两个分开的整数:N 和 K
样例输入:
8072216216 3
样例输出:
2006
输出解释:
2006^3=8072216216
好吧,这题的正解是二分,但是却有人用了pow函数来水分……而且还水对了……原理是这样的:假如有一个数a,要开n次方,则可以证明a的1/n次方等于a的n次方根!
所以,只需用pow(N,1/K)就可以了。但是要注意的一点是,int无法存储像N这样25位的数,但我们却可以用long double来存储,虽然空间大了,但精度同时也高了不少!只不过,其实这道题的数据出的还是很仁慈的,根据标准,好像还是可以装得下的。
但是最好的方法应该还是牛顿迭代法,代码就先不给出了。
Problem dictcow
Time Limit:10000MS Memory Limit:65536K
Total Submit:6 Accepted:3
Description
奶牛们有他们自己的字典,包含W(1 <= W <=600)个单词,每个单词包含不超过25个字母,
‘a’~‘z’,牛会接受到一个字符串S,长度L不大于300,因为牛发音不准,要删除
部分字母,使字符串可以由牛的字典中的单词组成,请你删去最少个数的字母,
使得字符串由字典中的单词组成。
PROBLEM NAME: dictcow
输入
* 第一行:两个整数: W 和 L
* 第二行:字符串S
* 3到.W+2 行:字典单词,每行一个
SAMPLE INPUT (file dictcow.in):
6 10
browndcodw
cow
milk
white
black
brown
farmer
输出
一行,输出最小删除的数
* SAMPLE OUTPUT (file dictcow.out):
2
这题不难,一个动规即可,但是主要是要找准动规的方式,本题的动规方法就是不断的在已知可以放入的字符串(可以通过删除得到的)后面不断地添加相应的单词,最后找出最大值即可。
Problem m2o
Time Limit:10000MS Memory Limit:65536K
Total Submit:40 Accepted:33
Description
奶牛们正在实验压缩算法,他们被那些在网上找到的好像压缩过的文本所吸引。他们相信一些用网络的人将连续的相同的字母用一个数字代替,这个数字表示连续的相同的字母的个数
例如 L33TSP34K 是
LTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTSPKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK的缩写
帮助奶牛们写一个程序,给出的文本用最多80个大写字母组成,用奶牛的运算法则将他们压缩
PROBLEM NAME: m2o
INPUT FORMAT:
第一行:最多80个大写字母组成的文本
SAMPLE INPUT (file m2o.in):
LTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTSPKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
OUTPUT FORMAT:
一行:压缩后的文本
SAMPLE OUTPUT (file m2o.out):
L33TSP34K
这题一看就是水题,我们组一次就AC了。原理不用讲了,主要就是要注意只有1个的时候不用压缩。这种方法很类似于DOS时代的一种图片压缩算法RLE,非常简单。
Problem diff
Time Limit:10000MS Memory Limit:65536K
Total Submit:65 Accepted:34
Description
给你两个整数 A 和 B (1 <= A <= 10^75, 1 <= B <=10^75), 求A与B的差 D (D = A - B). D 的范围保证在 -100,000..100,000.
PROBLEM NAME: diff
INPUT FORMAT:
* 第一行: 整数 A.
* 第二行: 整数 B
输入 (file diff.in):
3
2
输出(file diff.out):
1
OUTPUT DETAILS:
3-2 = 1.
这题也是非常之水的一道题,简简单单一个高精度就过了。不用多讲。但是老师好像说有一种不用高精度的方法。首先,注意到D的范围很小,只有正负十万。加起来也就二十万。所以,我们可以用枚举,枚举这二十万,离超时还远着呢。那么,我们枚举,用什么来算?用高精度加法吗?不对,因为D很小,所以,我们只需要看A和B的后六位就行了。这样,连枚举都省了!直接将后六位转成两个整数然后相减即可,用string输入,再用int存储,最后直接输出。就像真的A-B一样简单。这就是一个问题化简的方法,寻找题目中的漏洞,再用巧妙的方法击破。这样的速度显然快很多,不需要那样死算了,但是数据范围变大时可能就不行了。所以也要细心。
Problem Pen
Time Limit:10000MS Memory Limit:65536K
Total Submit:26 Accepted:8
Description
问题描述:
奶牛们正在学习写字.因为它们的蹄子太大,所以用的笔很重,导致它们写出来的句子中间没有空格.
现在FJ想知道奶牛们写了什么. 给出一个奶牛们写的句子(最多含有80个字符) 和一部奶牛字典(最多含有1000个单词) , 请根据字典中的单词给奶牛写的句子中间加上空格,使
句子中所有单词都在字典中出现, 假如有多种加空格的方法, 只输出"ambiguous" (保证最少有一种加空格的方法).
PROBLEM NAME: pen
输入说明
* 第一行: 奶牛们写的句子(最多包含80个字符
* 第二行: 一个数字N(N<=1000), 表示字典中有几个单词
第3~N+2行: 每行输入一个单词,表示字典中出现的单词.单词长度不超过10。
输出说明:
输出一个句子,即加空格后的句子,如有多种方法,只输出"ambiguous".
SAMPLE INPUT (file pen.in):
THESEPENSSUREAREHEAVY
14
ARE
BARN
FARMER
HEAVY
IS
JOHN
LIGHT
MILK
MOO
PENS
SURE
THESE
UNDER
USACO
SAMPLE OUTPUT (file pen.out):
THESE PENS SURE ARE HEAVY
这题其实就是一个完全背包,要求有且仅有这一种可能性。最简单的方法,直接暴力求解,时间复杂度为O(10^3*1000),基本上就是用四个嵌套的循环从第一个字符开始,枚举每一个单词,看看能不能放进去,如果能则更新当前的剩余字符串。但是如果用一下哈希,那可能会好很多,时间复杂度基本降到了O(10^2),但这题的数据范围不需要。
这次的题目出自USACO,下面是解题报告:
地理 geo
Time Limit:10000MS Memory Limit:65536K
Total Submit:26 Accepted:15
Description
奶牛们刚学习完地理课,知道地球是个球。他们非常震惊,满脑子都是球形。他们试图把地球表面看成一个NxN (1 <= N <= 100)的方格,但是顶端连接着底部、左边连接到右边。格子用坐标表示,左下角坐标为(1,1)。
例如: N=5时,牛从(1,3)位置向下走会到(5,3);从(2,5)向右走会到(2,1)位置。牛可以上、下、左、右和斜线方向走。
如果按照牛的模型,请计算依次行走 M(1 <= M <= 100) 格子的最短路径。
输入格式(file geo.in):
第一行:两个整数: N M。
下面M行:表示依次要行走的格子坐标:r c。
输出格式(file geo.out):
最少行走步数。
输入样例:
5 3
1 1
5 5
3 5
输出样例:
3
说明:先花一步从(1,1)走到(5,5),再花两步从(5,5)走到(3,5)。
#include <stdio.h> #include <algorithm> using namespace std; int main() { int N, M; int len = 0; int x=-1, y=-1; scanf("%d %d", &N, &M); for(int i = 0;i<M;i++) { int nx, ny; scanf("%d %d", &ny, &nx); ny--;nx--; if(x >= 0) { int moves = max(min(abs(nx-x),N-abs(nx-x)), min(abs(ny-y),N-abs(ny-y))); len += moves; } x = nx;y = ny; } printf("%d\n", len); return 0; }
这道题很简单主要的解题方法就是宽度优先搜索(或广度优先搜索),但是却有另外一个更好的方法,速度大大提高。
这真是一种聪明的作法!所花费的时间非常短,因为不需要那些广搜的复杂操作,只需计算即可。这个方法好像是由苏畅想出来的。
这种方法还可以解决另一道题:一个球从一个桌子的一角弹出,若它能一直弹下去,并给出初始其所经过的一些格子,问在第N次后这个球刚刚经过哪条边(刚刚经过的意思是指,还没有经过到下一条边)?这道题给出了轨迹,接下来的一些模拟也很简单了。具体的解法请看下面这张图:
单位 unit
Time Limit:10000MS Memory Limit:65536K
Total Submit:31 Accepted:7
Description
某星球上有很多计量系统,之间的计量单位的转换很繁琐。希望你能编程解决这个问题。
现有N (1 <= N <= 100) 个转换关系(比如:12 A 等于 1 B, 3 B等于 1 C等等 ),请计算指定的M (1 <= M <= 100) 个转换关系(比如:多少 A 等于 1 C).
输入格式( unit.in )
第一行:两个整数 N 和 M。
下面N行:每行有3个值:A S1 S2,A是一个小数,S1、S2是两个单词,它们之间用空格分开。表示 A 个 S1 等于 1个S2.
再后面有M行:每行两个单词 X Y,中间用空格分开,请你计算出1个Y相当于多少X。
输出格式 (file unit.out):
共M行:每行对应一个输入数据中的单位转换问题。答案为乘1000之后的四舍五入取整。保证答案不超过2^31.
样例输入:
4 1
12 inch foot
3 foot yard
5280 foot mile
0.0254 meter inch
meter mile
样例输出:
1609344
#define in cin #define out cout #include <algorithm> #include <iostream> #include <vector> #include <cmath> #include <map> #include <string> using namespace std; static map<string, int> no; static int pool = 0; static int getno(const string &a) { if (!no.count(a)) no[a] = pool++; return no[a]; } int main() { int N, M; double ratio[200][200]; in >> N >> M; for (int i = 0; i < 200; i++) for (int j = 0; j < 200; j++) ratio[i][j] = (i == j) ? 1.0 : HUGE_VAL; for (int i = 0; i < N; i++) { double r; string x, y; in >> r >> x >> y; int nx = getno(x); int ny = getno(y); ratio[nx][ny] = r; ratio[ny][nx] = 1.0 / r; } for (int y = 0; y < pool; y++) for (int x = 0; x < pool; x++) if (ratio[x][y] != HUGE_VAL) for (int z = 0; z < pool; z++) if (ratio[y][z] != HUGE_VAL && ratio[x][z] == HUGE_VAL) ratio[x][z] = ratio[x][y] * ratio[y][z]; for (int i = 0; i < M; i++) { string x, y; in >> x >> y; out << (int) round(1000.0 * ratio[getno(x)][getno(y)]) << "\n"; } return 0; }
这题仍然可以用广搜做。把那些转换的信息抽象成一个图中的链接,再用广搜一下子就好了。但是我觉得这个问题要求效率的话应该用像Dijkstra之类的多源最短路径算法,这样显然就能快很多。特别是在以后一些同样是单位转换,但走两条路得到的数量可能有所不同的情况下,最短路径显然改一下就好了。举个例子,假设美元汇人民币为1:6,人民币汇澳门币为1:2,而美元直接汇澳币为1:11,则这种情况下显然是先汇人民币再汇澳币划算。
问题 nroots
Time Limit:10000MS Memory Limit:65536K
Total Submit:31 Accepted:6
Description
一些牛在花园中工作---让他们考虑根,根的乘方是很容易.那些牛是考虑很大的根.
给整数 N(1<=N<=10^25) and K (3<=K<=10)计算整数B,N=B^K;
问题名:nroots
输入文件:
第一行:两个分开的整数:N 和 K
样例输入:
8072216216 3
样例输出:
2006
输出解释:
2006^3=8072216216
好吧,这题的正解是二分,但是却有人用了pow函数来水分……而且还水对了……原理是这样的:假如有一个数a,要开n次方,则可以证明a的1/n次方等于a的n次方根!
所以,只需用pow(N,1/K)就可以了。但是要注意的一点是,int无法存储像N这样25位的数,但我们却可以用long double来存储,虽然空间大了,但精度同时也高了不少!只不过,其实这道题的数据出的还是很仁慈的,根据标准,好像还是可以装得下的。
但是最好的方法应该还是牛顿迭代法,代码就先不给出了。
Problem dictcow
Time Limit:10000MS Memory Limit:65536K
Total Submit:6 Accepted:3
Description
奶牛们有他们自己的字典,包含W(1 <= W <=600)个单词,每个单词包含不超过25个字母,
‘a’~‘z’,牛会接受到一个字符串S,长度L不大于300,因为牛发音不准,要删除
部分字母,使字符串可以由牛的字典中的单词组成,请你删去最少个数的字母,
使得字符串由字典中的单词组成。
PROBLEM NAME: dictcow
输入
* 第一行:两个整数: W 和 L
* 第二行:字符串S
* 3到.W+2 行:字典单词,每行一个
SAMPLE INPUT (file dictcow.in):
6 10
browndcodw
cow
milk
white
black
brown
farmer
输出
一行,输出最小删除的数
* SAMPLE OUTPUT (file dictcow.out):
2
这题不难,一个动规即可,但是主要是要找准动规的方式,本题的动规方法就是不断的在已知可以放入的字符串(可以通过删除得到的)后面不断地添加相应的单词,最后找出最大值即可。
Problem m2o
Time Limit:10000MS Memory Limit:65536K
Total Submit:40 Accepted:33
Description
奶牛们正在实验压缩算法,他们被那些在网上找到的好像压缩过的文本所吸引。他们相信一些用网络的人将连续的相同的字母用一个数字代替,这个数字表示连续的相同的字母的个数
例如 L33TSP34K 是
LTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTSPKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK的缩写
帮助奶牛们写一个程序,给出的文本用最多80个大写字母组成,用奶牛的运算法则将他们压缩
PROBLEM NAME: m2o
INPUT FORMAT:
第一行:最多80个大写字母组成的文本
SAMPLE INPUT (file m2o.in):
LTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTSPKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
OUTPUT FORMAT:
一行:压缩后的文本
SAMPLE OUTPUT (file m2o.out):
L33TSP34K
这题一看就是水题,我们组一次就AC了。原理不用讲了,主要就是要注意只有1个的时候不用压缩。这种方法很类似于DOS时代的一种图片压缩算法RLE,非常简单。
Problem diff
Time Limit:10000MS Memory Limit:65536K
Total Submit:65 Accepted:34
Description
给你两个整数 A 和 B (1 <= A <= 10^75, 1 <= B <=10^75), 求A与B的差 D (D = A - B). D 的范围保证在 -100,000..100,000.
PROBLEM NAME: diff
INPUT FORMAT:
* 第一行: 整数 A.
* 第二行: 整数 B
输入 (file diff.in):
3
2
输出(file diff.out):
1
OUTPUT DETAILS:
3-2 = 1.
这题也是非常之水的一道题,简简单单一个高精度就过了。不用多讲。但是老师好像说有一种不用高精度的方法。首先,注意到D的范围很小,只有正负十万。加起来也就二十万。所以,我们可以用枚举,枚举这二十万,离超时还远着呢。那么,我们枚举,用什么来算?用高精度加法吗?不对,因为D很小,所以,我们只需要看A和B的后六位就行了。这样,连枚举都省了!直接将后六位转成两个整数然后相减即可,用string输入,再用int存储,最后直接输出。就像真的A-B一样简单。这就是一个问题化简的方法,寻找题目中的漏洞,再用巧妙的方法击破。这样的速度显然快很多,不需要那样死算了,但是数据范围变大时可能就不行了。所以也要细心。
Problem Pen
Time Limit:10000MS Memory Limit:65536K
Total Submit:26 Accepted:8
Description
问题描述:
奶牛们正在学习写字.因为它们的蹄子太大,所以用的笔很重,导致它们写出来的句子中间没有空格.
现在FJ想知道奶牛们写了什么. 给出一个奶牛们写的句子(最多含有80个字符) 和一部奶牛字典(最多含有1000个单词) , 请根据字典中的单词给奶牛写的句子中间加上空格,使
句子中所有单词都在字典中出现, 假如有多种加空格的方法, 只输出"ambiguous" (保证最少有一种加空格的方法).
PROBLEM NAME: pen
输入说明
* 第一行: 奶牛们写的句子(最多包含80个字符
* 第二行: 一个数字N(N<=1000), 表示字典中有几个单词
第3~N+2行: 每行输入一个单词,表示字典中出现的单词.单词长度不超过10。
输出说明:
输出一个句子,即加空格后的句子,如有多种方法,只输出"ambiguous".
SAMPLE INPUT (file pen.in):
THESEPENSSUREAREHEAVY
14
ARE
BARN
FARMER
HEAVY
IS
JOHN
LIGHT
MILK
MOO
PENS
SURE
THESE
UNDER
USACO
SAMPLE OUTPUT (file pen.out):
THESE PENS SURE ARE HEAVY
这题其实就是一个完全背包,要求有且仅有这一种可能性。最简单的方法,直接暴力求解,时间复杂度为O(10^3*1000),基本上就是用四个嵌套的循环从第一个字符开始,枚举每一个单词,看看能不能放进去,如果能则更新当前的剩余字符串。但是如果用一下哈希,那可能会好很多,时间复杂度基本降到了O(10^2),但这题的数据范围不需要。
相关文章推荐
- 来自洛谷八月月赛的一道数学问题 - 子串和 - 组合数学
- USACO 2015 US OPEN BRONZE 铜组 题解
- [转] 常用的CSS命名规则
- iOS应用分发与内测(一)
- 排列(decimal)
- Java实现生命周期管理机制
- 南海石门中学第六届创新班 2015-4-25 课时总结
- 南海石门中学第六届创新班 2015-5-16 课时总结
- 南海石门中学第六届创新班 2015-5-23 课时总结
- 南海石门中学第六届创新班 2015-5-30 课时总结
- 数学游戏(mathgame)解题方法 - N皇后位运算解法,14皇后亦在1秒中
- Friend解题报告 - 并查集练习
- Mode用cin的不超时程序
- Tree - NHIP第三题解题报告 - 并查集入门练习
- NHIP(2015)解题报告(第3题)
- IOS引入第三方冲突解决办法
- iOS在线音频播放FreeStreamer
- hdoj5247找连续数【rmq】
- iOS之@selector的函数传递多个参数
- linux下redis安装