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

 

传话游戏

描述

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 

 

 

样例输入
2
4 3
ship sheep
sinking thinking
thinking sinking
the ship is sinking
10 5
tidy tiny
tiger liar
tired tire
tire bear
liar bear
a tidy tiger is tired
样例输出
Case #1: the sheep is thinking
Case #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

 

 

样例输入
3
3 3 8
4 5 13
7 14 86
样例输出
Case #1: 5
Case #2: 18
Case #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

 

样例输入
2
5
1 2 5
1 3 20
2 4 30
4 5 15
2
3 4
3 5
5
1 4 32
2 3 100
3 5 45
4 5 60
2
1 4
1 3
样例输出
Case #1:
No
Yes
Case #2:
No
Yes
/* 
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;
}


 
 


你可能感兴趣的:(2013编程之美)