地理 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次方根!
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