2016年天梯赛初赛题集(L1 - L2)

注意使用STL,可以很省事的~~~

    • 7-1 到底有多二 (15 分)
    • 7-2 大笨钟 (10 分)
    • 7-3 谁先倒 (15 分)
    • 7-4 帅到没朋友 (20 分)
    • 7-5 重要的话说三遍 (5 分)
    • 7-6 奇偶分家 (10 分)
    • 7-7 输出GPLT (20 分)
    • 7-8 后天 (5 分)
    • 7-9 抢红包 (25 分)
    • 7-10 排座位 (25 分)
    • 7-11 玩转二叉树 (25 分)
    • 7-12 关于堆的判断 (25 分)

7-1 到底有多二 (15 分)

思路

字符串处理,统计2 的个数,判断是不是负数和是不是偶数即可。输出%需要两个%%。

AC代码

#include 
using namespace std;

int main(){
	
	string s;
	cin >> s;
	
	double a = 0, b = 0, c = 1, d = 1;
	int len = s.size();
	for(int i = 0; i < len; i++){
		if(s[i] == '-') c += 0.5;
		else{
			int tmp = s[i] - '0';
			if(tmp == 2) a++;
			b++;
			if(i+1 == len && tmp % 2 == 0) d++;
		}
	}
	
	double res = a / b * c * d * 100;
	printf("%.2lf%%\n", res);

	return 0;
}

7-2 大笨钟 (10 分)

思路

根据题意模拟即可。输出自动补零的格式: %0Xd,X为要保留几位数

AC代码

#include 
using namespace std;

int main(){
	
	int a, b; char c;
	cin >> a >> c >> b;
	if(a < 12 || (a == 12 && b == 0)) printf("Only %02d:%02d.  Too early to Dang.", a, b);
	else{
		if(b != 0) a++;
		for(int i = 1; i <= a-12; i++) printf("Dang");
	}

	return 0;
}

7-3 谁先倒 (15 分)

思路
根据题意一遍输入一遍判断即可,注意要把所有数据都输入

AC代码

#include 
using namespace std;

int main(){
	
	int a, b;
	cin >> a >> b;
	int m, x = 0, y = 0;
	cin >> m;
	int A, AA, B, BB;
	for(int i = 1; i <= m; i++){
		cin >> A >> AA >> B >> BB;
		if(x > a || y > b) continue;
		if(A + B == AA && A + B == BB) continue;
		else if(A + B == AA) x++;
		else if(A + B == BB) y++;
	}
	
	if(x > a) cout << "A" << endl << y << endl;
	else cout << "B" << endl << x << endl;
	
	return 0;
}

7-4 帅到没朋友 (20 分)

思路
用 map 来统计每个人在朋友圈里出现的次数,如果一个人出现零次,那就是没朋友的。
注意处理只有一个人的朋友圈。
注意处理输出的格式(补零 and 结尾无空格) 和 题目要求

AC代码

#include 
using namespace std;

map<int, int> v;
vector<int> res;

int main(){
	
	int n;
	cin >> n;
	int m, x;
	for(int i = 1; i <= n; i++){
		cin >> m;
		if(m == 1) cin >> x;
		else{
			for(int i = 1; i <= m; i++){
				cin >> x;
				v[x]++;
			}
		}
	}
	

	cin >> m;
	for(int i = 1; i <= m; i++){
		cin >> x;
		if(v[x] == 0){
			res.push_back(x);
			v[x]++;
		}
	}
	
	int len = res.size();
	if(len == 0) printf("No one is handsome\n");
	else{
		for(int i = 0; i < len; i++){
			printf("%05d", res[i]);
			if(i+1 == len) printf("\n");
			else printf(" ");
		}
	}
	
	return 0;
}

7-5 重要的话说三遍 (5 分)

思路
福利题,最好直接赋值题目上的格式,不要手敲

AC代码

#include 
using namespace std;


int main(){
	
	cout << "I'm gonna WIN!" << endl;
	cout << "I'm gonna WIN!" << endl;
    cout << "I'm gonna WIN!" << endl;
    
	return 0;
}

7-6 奇偶分家 (10 分)

思路
% 2 或者 & 1 判断奇偶即可。
& 是位运算,可以看看这个 传送门~~~

AC代码

#include 
using namespace std;


int main(){
	
	int n;
	cin >> n;
	int x = 0, y = 0, num;
	for(int i = 1; i <= n; i++){
		cin >> num;
		if(num&1) x++;
		else y++;
	}
	
	cout << x << " " << y << endl;
	
	return 0;
}

7-7 输出GPLT (20 分)

思路
分别统计 RPLT 出现的次数,依次输出即可

AC代码

#include 
using namespace std;

int v[5] = {0};

int main(){
	
	string s;
	cin >> s;
	
	int len = s.size();
	for(int i = 0; i < len; i++){
		if(s[i] == 'g' || s[i] == 'G') v[1]++;
		else if(s[i] == 'p' || s[i] == 'P') v[2]++;
		else if(s[i] == 'l' || s[i] == 'L') v[3]++;
		else if(s[i] == 't' || s[i] == 'T') v[4]++;
	}
	
	while(v[1] + v[2] + v[3] + v[4] != 0){
		if(v[1]) cout << "G", v[1]--;
		if(v[2]) cout << "P", v[2]--;
		if(v[3]) cout << "L", v[3]--;
		if(v[4]) cout << "T", v[4]--;
	}
	
	
	return 0;
}

7-8 后天 (5 分)

思路
加 2,然后对 7 取模既可。也可以连写 if - else。

AC代码

#include 
using namespace std;

int main(){
	
	int n;
    cin >> n;
    n = (n+2) % 7;
    if(n == 0) n = 7;
    cout << n << endl;
	
	return 0;
}

7-9 抢红包 (25 分)

思路
按照题意统计即可。注意发红包的人要减去对应的财富,最后结构体排序(写 cmp 即可,不必重载 小于号)。

AC代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define chushi(a, b) memset(a, b, sizeof(a))
#define endl "\n"
const double eps = 1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const int maxn = 1e5 + 5;

using namespace std;

int num[maxn] = {0};
double sum[maxn] = {0};

typedef struct Node{
	int id;
	int num;
	double sum;
} node;

bool cmp(node A, node B){
	if(fabs(A.sum - B.sum) < 1e-6){
		if(A.num == B.num) return A.id < B.id;      
		return A.num > B.num;
	}
	return A.sum > B.sum;
}

node v[maxn];

int main(){
	
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++){
		int k;
		cin >> k;
		int n; double p;
		for(int j = 1; j <= k; j++){
			cin >> n >> p;
			num[n]++;
			sum[n] += p;
			sum[i] -= p;
		}
	}
	
	for(int i = 1; i <= n; i++){
		v[i].id = i;
		v[i].num = num[i];
		v[i].sum = sum[i];
	}
	
	sort(v+1, v+1+n, cmp);
	
	for(int i = 1; i <= n; i++) printf("%d %.2lf\n", v[i].id, v[i].sum/100);	
	
	return 0;
}

7-10 排座位 (25 分)

思路
并查集统计朋友关系(直接和间接),用二维数组记录直接的敌对关系,依次判断输出即可

AC代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define chushi(a, b) memset(a, b, sizeof(a))
#define endl "\n"
const double eps = 1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const int maxn = 1e5 + 5;

using namespace std;

int v[105][105] = {0};

int f[105];

int find(int x){
	if(f[x] == x) return x;
	else return f[x] = find(f[x]);
}

void join(int x, int y){
	int fx = find(x);
	int fy = find(y);
	
	if(fx != fy) f[fy] = fx;
}

int main(){
	
	int n, m, k;
	cin >> n >> m >> k;
	
	for(int i = 1; i <= n; i++) f[i] = i;
	
	int x, y, flag;
	while(m--){
		cin >> x >> y >> flag;
		v[y][x] = v[x][y] = flag;
		if(flag == 1) join(x, y);
	}
	
	while(k--){
		cin >> x >> y;
		
		if(v[x][y] != -1 && find(x) == find(y)) cout << "No problem" << endl;
		else if(v[x][y] == -1 && find(x) == find(y)) cout << "OK but..." << endl;
		else if(v[x][y] == -1) cout << "No way" << endl;
		else cout << "OK" << endl;
	}
	return 0;
}

7-11 玩转二叉树 (25 分)

思路
由中序和前序建树,用后序遍历的顺序交换子树达到镜面对称,BFS层次输出

AC代码

#include 
#include 

using namespace std;

int a[55];	// 中序 
int b[55];	// 前序

typedef struct NOde{
	int data;
	int l;
	int r;
} node;

node t[100000];
int cnt = 0;

int build(int la, int ra, int lb, int rb){
	
	if(la > ra) return -1;
	
	int tmp = ++cnt;
	t[tmp].data = b[lb];
	
	int x = la;
	while(a[x] != b[lb]) x++;
	int len = x - la;
	
	t[tmp].l = build(la, x - 1, lb+1, lb + len);
	t[tmp].r = build(x + 1, ra, lb + len + 1, rb);
	 
	return tmp;
}

void DFS(int x){
	
	if(x == -1) return;
	
	DFS(t[x].l);
	DFS(t[x].r);
	
	swap(t[x].l, t[x].r);
}

void BFS(int n){
	
	queue<node> qu;
	qu.push(t[1]);
	
	int num = 0;
	
	while(!qu.empty()){
		node x = qu.front();
		qu.pop();
		
		cout << x.data;
		if(++num == n) cout << endl;
		else cout << " ";
		
		if(x.l != -1) qu.push(t[x.l]);
		if(x.r != -1) qu.push(t[x.r]);
	}
	
}


int main(int argc, char** argv) {
	
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++) cin >> a[i];
	for(int i = 1; i <= n; i++) cin >> b[i];
	
	build(1, n, 1, n);
	
	DFS(1);
	
	BFS(n);
	
	return 0;
}

7-12 关于堆的判断 (25 分)

思路
根据题意模拟即可,注意处理输入

AC代码

#include 
#include 

using namespace std;

int a[1005];	

void insert_(int i, int num){
	while(a[i] < a[i/2] && i != 1){
		swap(a[i], a[i/2]);
		i >>= 1;
	}
	return;
}

int find(int x, int n){
	for(int i = 1; i <= n; i++){
		if(a[i] == x) return i;
	}
	return 0;
}

int main(int argc, char** argv) {
	
	int n, m;
	cin >> n >> m;

	for(int i = 1; i <= n; i++){
		cin >> a[i];
		insert_(i, a[i]);
	}
	
	while(m--){
		int x;
		cin >> x;
		string s;
		cin >> s;
		if(s == "and"){
			int y;
			cin >> y;
			cin >> s; cin >> s;
			int fx = find(x, n);
			int fy = find(y, n);
			if(fx / 2 == fy / 2) cout << "T" << endl;
			else cout << "F" << endl;
		}
		else{
			cin >> s;
			if(s == "a"){
				cin >> s; cin >> s;
				int y;
				cin >> y;
				int fx = find(x, n);
				int fy = find(y, n);
				if(fx / 2 == fy) cout << "T" << endl;
				else cout << "F" << endl;
			}
			else{
				cin >> s;
				if(s == "root"){
					if(a[1] == x) cout << "T" << endl;
					else cout << "F" << endl;
				}
				else{
					cin >> s;
					int y;
					cin >> y;
					int fx = find(x, n);
					int fy = find(y, n);
					if(fy / 2 == fx) cout << "T" << endl;
					else cout << "F" << endl;
				}
			}
		}
	}

	return 0;
}

你可能感兴趣的:(题解)