Beauty of Programming 2013资格赛题解(鄙人参照了no.1的程序)

来源:互联网 发布:火车票网上抢票软件 编辑:程序博客网 时间:2024/05/17 20:35

传话游戏

描述

Alice和Bob还有其他几位好朋友在一起玩传话游戏。这个游戏是这样进行的:首先,所有游戏者按顺序站成一排,Alice站第一位,Bob站最后一位。然后,Alice想一句话悄悄告诉第二位游戏者,第二位游戏者又悄悄地告诉第三位,第三位又告诉第四位……以此类推,直到倒数第二位告诉Bob。两位游戏者在传话中,不能让其他人听到,也不能使用肢体动作来解释。最后,Bob把他所听到的话告诉大家,Alice也把她原本所想的话告诉大家。 

由于传话过程中可能出现一些偏差,游戏者越多,Bob最后听到的话就与Alice所想的越不同。Bob听到的话往往会变成一些很搞笑的东西,所以大家玩得乐此不疲。经过几轮游戏后,Alice注意到在两人传话中,有些词汇往往会错误地变成其他特定的词汇。Alice已经收集到了这样的一个词汇转化的列表,她想知道她的话传到Bob时会变成什么样子,请你写个程序来帮助她。

输入

输入包括多组数据。第一行是整数 T,表示有多少组测试数据。每组数据第一行包括两个整数 N 和 M,分别表示游戏者的数量和单词转化列表长度。随后有 M 行,每行包含两个用空格隔开的单词 a 和 b,表示单词 a 在传话中一定会变成 b。输入数据保证没有重复的 a。最后一行包含若干个用单个空格隔开的单词,表示Alice所想的句子,句子总长不超过100个字符。所有单词都只包含小写字母,并且长度不超过20,同一个单词的不同时态被认为是不同的单词。你可以假定不在列表中的单词永远不会变化。

输出

对于每组测试数据,单独输出一行“Case #c: s”。其中,c 为测试数据编号,s 为Bob所听到的句子。s 的格式与输入数据中Alice所想的句子格式相同。

数据范围

1 ≤ T ≤ 100

小数据:2 ≤ N ≤ 10, 0 ≤ M ≤ 10 

大数据:2 ≤ N ≤ 100, 0 ≤ M ≤ 100 


样例输入
24 3ship sheepsinking thinkingthinking sinkingthe ship is sinking10 5tidy tinytiger liartired tiretire bearliar beara tidy tiger is tired
样例输出
Case #1: the sheep is thinkingCase #2: a tiny bear is bear
//Source code 简单的模拟#include <iostream>#include <map>#include <string>#include <cstdlib>#include <cstdio>using namespace std;int main(){    int T;    cin >> T;    for(int iCase = 1; iCase <= T; ++iCase)    {int n, m;cin >> n >> m;map<string, string> convert;for(int i = 0; i < m; ++i){    string key, value;    cin >> key >> value;    convert[key] = value;}string word ;string result;while( cin >> word  ){    int steps = n - 1;    while( convert.count(word) && steps)    {word = convert[word];--steps;    }    result += word;    result += " ";    if( getchar() == '\n')break;}cout << "Case #" << iCase << ": " << result << endl;    }    return 0;}

长方形

时间限制: 1000ms 内存限制: 256MB

描述

在 N 条水平线与 M 条竖直线构成的网格中,放 K 枚石子,每个石子都只能放在网格的交叉点上。问在最优的摆放方式下,最多能找到多少四边平行于坐标轴的长方形,它的四个角上都恰好放着一枚石子。

输入

输入文件包含多组测试数据。

第一行,给出一个整数T,为数据组数。接下来依次给出每组测试数据。

每组数据为三个用空格隔开的整数 N,M,K。

输出

对于每组测试数据,输出一行"Case #X: Y",其中X表示测试数据编号,Y表示最多能找到的符合条件的长方形数量。所有数据按读入顺序从1开始编号。

数据范围

1 ≤ T ≤ 100

0 ≤ K ≤ N * M

小数据:0 < N, M ≤ 30

大数据:0 < N, M ≤ 30000

样例输入
33 3 84 5 137 14 86
样例输出
Case #1: 5Case #2: 18Case #3: 1398
//Source code : k = x * y + r , 枚举x与y,计算出C(x,2)*C(y,2) + C(r,2)*y的最大值#include <iostream>#include <vector>using namespace std;int Func(int n){    return n*(n-1)/2;}int main(){    int T;    cin >> T;    for(int iCase = 1; iCase <= T; ++iCase)    {int n, m;cin >> n >> m;int k;cin >> k;int ans = 0;for(int x = 2; x <= n; ++x){    int y = k / x;    int r = k % x;    if( y > m || (y == m && r) )continue;    ans = max(ans, Func(x)*Func(y) + y*Func(r));}cout << "Case #" << iCase << ": " << ans << endl;    }    return 0;}

树上三角形

时间限制: 2000ms 内存限制: 256MB

描述

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

输入

输入数据的第一行包含一个整数 T,表示数据组数。

接下来有 T 组数据,每组数据中:

第一行包含一个整数 N,表示树上节点的个数(从 1 到 N 标号)。

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

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

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

输出

对于每组数据,先输出一行"Case #X:",其中X为数据组数编号,从 1 开始。

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

数据范围

1 ≤ T ≤ 5

小数据:1 ≤ N ≤ 100, 1 ≤ M ≤ 100, 1 ≤ len ≤ 10000

大数据:1 ≤ N ≤ 100000, 1 ≤ M ≤ 100000, 1 ≤ len ≤ 1000000000

样例输入
251 2 51 3 202 4 304 5 1523 43 551 4 322 3 1003 5 454 5 6021 41 3
样例输出
Case #1:NoYesCase #2:NoYes
/* Source code: 因为就只有n条边,所以其实就是一个树状的图。判断是否存在三条边能够组成三角形时,这里采用了枚举三角形的最大边。首先对边进行排序,边依次为e1,e2,...,em,那么最有可能与ei(i>=3)构成三角形的另外两条较小的边就是e(i-1), e(i-2),因为小于ei的任何两条边差绝对值都一定小于ei,但是只有e(i-1)+e(i-2)有最大的可能性大于ei,如果e(i-1)+e(i-2)<=ei,那么以ei为最大边的三角形不存在。依次枚举ei(i>=3)即可得出我们想要的结论。   大数据情况下,由于最大边长为10^9,但是如果有e(i)+e(i+1)<=e(i+3),根据斐波那契数列,那么e(50)>10^9,这跟题目条件相悖。所以边数大于等于50时,并且最大边长又小于10^9时,一定可以找到其中三条边能够组成三角形。*/#include <iostream>#include <vector>#include <queue>#include <utility>#include <algorithm>using namespace std;typedef pair<int, int> EDGE;vector<vector<EDGE> > links;vector<EDGE> parent;vector<int> deepth;void BFS(int root){    queue<int> q;    q.push(root);    deepth[root] = 0;    parent[root] = make_pair(0, 0);    while( !q.empty() )    {int p = q.front();q.pop();int pp = parent[p].first;for(int i = 0; i < links[p].size(); ++i){    int c = links[p][i].first;    int w = links[p][i].second;    if(c == pp)continue;    q.push(c);    parent[c] = make_pair(p, w);    deepth[c] = deepth[p] + 1;}    }}/*void DFS(int p, int c, int d){    deepth[c] = d;    for(int i = 0; i < links[c].size(); ++i)    {int nn = links[c][i].first;int weight = links[c][i].second;if(nn == p)    continue;parent[nn] = make_pair(c, weight);DFS(c, nn, d+1);    }}*/bool Judge(int s, int d){    vector<int> edges;    while(s != d && edges.size() <= 50)    {if(deepth[s] < deepth[d]){    edges.push_back(parent[d].second);    d = parent[d].first;}else if(deepth[d] < deepth[s]){    edges.push_back(parent[s].second);    s = parent[s].first;}else {    edges.push_back(parent[d].second);    d = parent[d].first;    edges.push_back(parent[s].second);    s = parent[s].first;}    }    sort(edges.begin(), edges.end());    for(int i = 2; i < edges.size(); ++i)    {if(edges[i-2] + edges[i-1] > edges[i])    return true;    }    return false;}int main(){    int T;    cin >> T;    for(int iCase = 1; iCase <= T; ++iCase)    {int n; cin >> n;links.clear();links.resize(n+1);for(int i = 1; i < n; ++i){    int s, d, w;    cin >> s >> d >> w;    links[s].push_back(make_pair(d, w));    links[d].push_back(make_pair(s, w));}parent.clear();parent.resize(n+1);deepth.clear();deepth.resize(n+1);//DFS(0, 1, 0);BFS(1);int m; cin >> m;cout << "Case #" << iCase << ":" << endl; for(int i = 0; i < m; ++i){    int s, d;    cin >> s >> d;    cout << (Judge(s, d)?"Yes":"No") << endl;}    }    return 0;}




原创粉丝点击