2016年天梯赛决赛题集

L3 题解链接:https://blog.csdn.net/mldl_/article/details/123311743


7-1 正整数A+B (15 分)

思路

输入一行字符串,再处理

AC代码

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

int get_num(string s){
	int len = s.size();
	int res = 0;
	for(int i = 0; i < len; i++){
		int tmp = s[i] - '0';
		if(tmp < 0 || tmp > 9) return -1;
		else res = res * 10 + tmp;
	}
	
	if(res > 1000 || res < 1) return -1;
	return res;
}

int main(int argc, char** argv) {
	
	string s, a, b;
	getline(cin, s);
	int len = s.size(), f = 1;
	for(int i = 0; i < len; i++){
		if(s[i] == ' ' && f) f = 0;
		else if(f) a += s[i];
		else b += s[i];
	}

	int x = get_num(a);
	int y = get_num(b);
	
	if(x + y == -2) cout << "? + ? = ?" << endl;
	else if(x == -1) cout << "? + " << y << " = ?" << endl;
	else if(y == -1) cout << x << " + ? = ?" << endl;
	else cout << x << " + " << y << " = " << x + y << endl;
	
	return 0;
}

7-2 I Love GPLT (5 分)

思路

签到题。

AC代码

#include <iostream>
#include <bits/stdc++.h>

using namespace std;


int main(int argc, char** argv) {
	
	string s = "I Love GPLT";
	int len = s.size();
	
	for(int i = 0; i < len; i++) cout << s[i] << endl;
	
	return 0;
}

7-3 出租 (20 分)

思路

给出现的数字按顺序编号,然后再按照题意输出即可。

AC代码

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

int main(int argc, char** argv) {
	
	string s;
	cin >> s;
	
	string ss = s;
	sort(ss.begin(), ss.end());
	int n = unique(ss.begin(), ss.end()) - ss.begin();
	cout << "int[] arr = new int[]{";
	for(int i = n-1; i >= 0; i--){
		cout << ss[i];
		if(i == 0) cout << "};" << endl;
		else cout << ",";
	}
	
	int len = s.size();
	reverse(ss.begin(), ss.begin()+n);
	cout << "int[] index = new int[]{";
	for(int i = 0; i < len; i++){
		for(int j = 0; j < n; j++){
			if(s[i] == ss[j]){
				cout << j;
				if(i+1 == len) cout << "};" << endl;
				else cout << ",";
				break;
			}
		}
	}
	
	return 0;
}

7-4 判断素数 (10 分)

思路

O(根号n) 的时间复杂度判断素数,特判 0 和 1

AC代码

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

int main(int argc, char** argv) {
	
	int ncase;
	cin >> ncase;
	while(ncase--){
		long long n;
		cin >> n;
		int f = 1;
		for(long long i = 2; i * i <= n; i++){
			if(n % i == 0){
				f = 0;
				break;
			}
		}
		if(n < 2) f = 0;
		if(f) cout << "Yes" << endl;
		else cout << "No" << endl;
	}
	
	return 0;
}

7-5 是不是太胖了 (5 分)

思路

按题意计算即可

AC代码

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

int main(int argc, char** argv) {
	
	double num;
	cin >> num;
	
	num = (num - 100) * 0.9 * 2;

	printf("%.1lf\n", num);
	
	return 0;
}

7-6 一帮一 (15 分)

思路

暴力匹配即可。

AC代码

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

string name[55];
int flag[55];
int v[55] = {0};


int main(int argc, char** argv) {
	
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++) cin >> flag[i] >> name[i];
	
	for(int i = 1; i <= n; i++){
		if(v[i]) continue;
		for(int j = n; j >= 1; j--){
			if(v[j]) continue;
			if(flag[i] + flag[j] == 1){
				v[i] = v[j] = 1;
				cout << name[i] << " " << name[j] << endl;
				break;
			}
		}
	}
	
	return 0;
}

7-7 到底是不是太胖了 (10 分)

思路

分三段判断既可。

AC代码

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

int main(int argc, char** argv) {
	
	int ncase;
	cin >> ncase;
	while(ncase--){
		double h, w;
		cin >> h >> w;
		double tmp = (h - 100) * 0.9 * 2;
		if(fabs(w - tmp) * 10 < tmp) cout << "You are wan mei!" << endl;
		else if(w > tmp) cout << "You are tai pang le!" << endl;
		else cout << "You are tai shou le!" << endl;
	}

	return 0;
}

7-8 Left-pad (20 分)

思路

字符串模拟。

AC代码

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int main(){


    int n; char c;
    cin >> n >> c;
    getchar();
    string s;
    getline(cin, s);

    int len = s.size();
    if(n <= len){
        for(int i = len - n; i < len; i++) cout << s[i];
    }
    else{
        int l = n - len;
        for(int i = 1; i <= l; i++) cout << c;
        cout << s << endl;
    }



    return 0;
}

7-9 红色警报 (25 分)

思路

并查集统计联通块的个数(无向图,在同一个联通块的点是一个集合,有相同的祖先)。
如果这个点不影响联通性,这个点将成为一个新的联通块,联通块的个数加一。
如果这个点影响联通性,不但这个点将成为一个新的联通块,而且原来的一个联通块将分裂成多个连通块。这时联通块的个数最少加 2.
在这里插入图片描述
如果删掉 B点,B 将成为一个新的联通快,联通块的个数变为 2。
如果删掉 A点,联通块的个数变为 4。

AC代码

#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#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;

bool ma[505][505] = {0};

int f[505];
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[fx] = fy;
	}
}

int main(){
	
	int n, m;
	cin >> n >> m;
	int u, v;
	for(int i = 1; i <= n; i++) f[i] = i;
	for(int i = 1; i <= m; i++){
		cin >> u >> v;
		ma[u+1][v+1] = 1;
		ma[v+1][u+1] = 1;
		join(u+1, v+1);
	}
	
	int sum = 0;
	for(int i = 1; i <= n; i++) if(f[i] == i) sum++;
	
	int k, x;
	cin >> k;
	for(int i = 1; i <= k; i++){
		cin >> x;
		for(int i = 1; i <= n; i++) ma[i][x+1] = ma[x+1][i] = 0;
		int num = 0;
		for(int i = 1; i <= n; i++) f[i] = i;
		for(int i = 1; i <= n; i++){
			for(int j = i+1; j <= n; j++){
				if(ma[i][j]) join(i, j);
			}
		}
		for(int i = 1; i <= n; i++) if(f[i] == i) num++;
		if(num > sum+1) cout << "Red Alert: City " << x << " is lost!" << endl;
		else cout << "City " << x << " is lost." << endl;
		sum = num;
	}
	
	if(k == n) cout << "Game Over." << endl;
	
	return 0;
}

7-10 列车调度 (25 分)

思路

Dilworth定理:最少下降子序列个数等于最长上升子序列的长度。
证明自行百度。
这里要二分优化查找,不然会 TI 掉两个点。

AC代码

#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#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[maxn];

int main(){

	int n;
    cin >> n;
    int x;
    for(int i = 1; i <= n; i++) v[i] = maxn;
    for(int i = 1; i <= n; i++){
        cin >> x;
        int ind = lower_bound(v+1, v+1+n, x) - v;
		v[ind] = x;
    }

    cout << lower_bound(v+1, v+1+n, maxn) - v - 1 << endl;

	return 0;
}


7-11 互评成绩 (25 分)

思路
按照题意模拟即可。

AC代码

#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#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;

vector<double> res;

double v[maxn];

int main(){

	int n, k, m;
	cin >> n >> k >> m;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= k; j++) cin >> v[j];
        sort(v+1, v+1+k);
        double sum = 0;
        for(int j = 2; j < k; j++) sum += v[j];
        res.push_back((sum / (1.0 * k - 2)));
    }

    sort(res.begin(), res.end());
	
    for(int i = m; i >= 1; i--){
        printf("%.3lf", res[n-i]);
        if(i != 1) printf(" ");
        else printf("\n");
    }

	return 0;
}

7-12 愿天下有情人都是失散多年的兄妹 (25 分)

思路

map 离散化编号。
map 存性别。
DFS 找祖先,让孩子指向父母,建图。
注意:父亲隐含是男性,母亲隐含是女性,不然会 wa

AC代码

#include <bits/stdc++.h>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#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;

map<string, int> id;
int cnt = 0;
int get_id(string s){
	if(id[s] == 0) return id[s] = ++cnt;
	else return id[s];
}

int f[maxn];
int m[maxn];

map<string, char> sex;

int V[maxn];

int flag;

void DFS(int a, int d){
	
	if(d > 4) return;
	if(!flag) return;
	if(a == -1) return;
	
	if(V[a] != 0) flag = 0;
	else V[a]++;
	
	if(f[a] != -1) DFS(f[a], d+1);
	if(m[a] != -1) DFS(m[a], d+1);
}

int main(){

	chushi(f, -1); chushi(m, -1); id["-1"] = -1;
	
	int n;
	cin >> n;
	string name, ff, mm; char se;
	for(int i = 1; i <= n; i++){
		cin >> name >> se >> ff >> mm;
		f[get_id(name)] = get_id(ff);
		m[get_id(name)] = get_id(mm);
		if(ff != "-1") sex[ff] = '1';
		if(mm != "-1") sex[mm] = '0';
		sex[name] = se;
	}
	
	int k;
	cin >> k;
	while(k--){
		string a, b;
		cin >> a >> b;
		if(sex[a] == sex[b]) cout << "Never Mind" << endl;
		else{
			flag = 1; chushi(V, 0);
			DFS(get_id(a), 0);
			DFS(get_id(b), 0);
			if(flag) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
	}

	return 0;
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值