目录
已给出AC代码的题目如有不懂可在评论区提问哦,也欢迎大佬指错,或者提供更好的思路
L1部分
L1 - 1 编程解决一切
L1-097 编程解决一切 - 团体程序设计天梯赛-练习集 (pintia.cn)
L1 - 2 再进去几个人
L1-098 再进去几个人 - 团体程序设计天梯赛-练习集 (pintia.cn)
#include<iostream>
using namespace std;
int main(){
int a,b;cin >> a >> b;
cout << b - a;
return 0;
}
L1 - 3 帮助色盲
L1-099 帮助色盲 - 团体程序设计天梯赛-练习集 (pintia.cn)
#include<iostream>
using namespace std;
int main(){
int a,b;cin >> a >> b;
if(b == 0){
if(a == 0){
cout << "biii" << endl;
cout << "stop" << endl;
}
else if(a == 1){
cout << "dudu" << endl;
cout << "move" << endl;
}
else if(a == 2){
cout << "-" << endl;
cout << "stop" << endl;
}
}
else if(b == 1){
if(a == 0){
cout << "-" << endl;
cout << "stop" << endl;
}
else if(a == 1){
cout << "-" << endl;
cout << "move" << endl;
}
else if(a == 2){
cout << "-" << endl;
cout << "stop" << endl;
}
}
return 0;
}
L1 - 4 四项全能
L1-100 四项全能 - 团体程序设计天梯赛-练习集 (pintia.cn)
#include<iostream>
using namespace std;
int main(){
int n,m;cin >> n >> m;
int sum = 0;
for(int i = 0;i < m;i++){
int t;cin >> t;sum += t;
}
int tem = n * (m - 1);
if(tem > sum)cout << "0" << endl;
else cout << sum - tem << endl;
return 0;
}
L1 - 5 别再来这么多猫娘了!
L1-101 别再来这么多猫娘了! - 团体程序设计天梯赛-练习集 (pintia.cn)
易错:<censored> 也可能时违禁词....(家人们,谁懂啊~)
思路:把违禁词存起来,然后一个一个的去找。
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
using namespace std;
vector<string> ban;
int main() {
int n; cin >> n;
getchar();
string t;
for (int i = 0; i < n; i++) {
cin >> t; ban.push_back(t);
getchar();
}
int tot; cin >> tot; getchar();
string str; getline(cin, str);
int c = 0;
string l = "=========="; //用"......"可能不过
for (int i = 0; i < ban.size(); i++) {
int pos = str.find(ban[i]);
while (pos != -1) { //相同的屏蔽词可能出现不止一次
str.replace(str.begin() + pos, str.begin() + pos + ban[i].length(), l);
c++;
pos = str.find(ban[i]);
}
}
int pos = str.find(l);
while (pos != -1) {
str.replace(str.begin() + pos, str.begin() + pos + l.length(), "<censored>");
pos = str.find(l);
}
if (c >= tot) {
cout << c << endl;
cout << "He Xie Ni Quan Jia!" << endl;
}
else {
cout << str << endl;
}
return 0;
}
L1 - 6 兰州牛肉面
L1-102 兰州牛肉面 - 团体程序设计天梯赛-练习集 (pintia.cn)
#include<iostream>
#include<cstdio>
using namespace std;
double a[200][2];
int main(){
int n;cin >> n;
for(int i = 1;i <= n;i++){
cin >> a[i][0];
}
int p,b;
while(cin >> p >> b && p && b){
a[p][1] += b;
}
double sum = 0;
for(int i = 1;i <= n;i++){
printf("%.0lf\n",a[i][1]);
sum += a[i][0] * a[i][1];
}
printf("%.2lf",sum);
return 0;
}
L1 - 7 整数的持续性
L1-103 整数的持续性 - 团体程序设计天梯赛-练习集 (pintia.cn)
应该没什么坑。。直接模拟
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int f(int x) { //求下一个数
int res = 1;
while (x)res *= x % 10, x /= 10;
return res;
}
vector<int> res; //记录答案
int m;
int main() {
int a, b; cin >> a >> b;
for (int i = a; i <= b; i++) {
int cnt = 0,t = i;
while (t / 10) { //如果是一个个位数,则跳出循环
t = f(t);
cnt++;
}
if (cnt > m) {
res.clear();
m = cnt;
res.push_back(i);
}
else if (cnt == m) {
res.push_back(i);
}
}
cout << m << endl;
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " \n"[i == res.size() - 1];
}
return 0;
}
L1 - 8 九宫格
L1-104 九宫格 - 团体程序设计天梯赛-练习集 (pintia.cn)
易错:输入不一定合法
难点:对于下标处理
思路:定义数组a[行][列],对行处理就像输入那样,对列处理把 i 和 j 的位置交换一下,
对于宫格的处理可以进行打表
#include<iostream>
#include<cstring>
using namespace std;
const int N = 11;
const int n = 9;
int a[N][N];
int vis[N];
int gp[3][2] = {{1,3},{4,6},{7,9}};
void solve(){
int f = 1; //标记该九宫格是否合法
for(int i = 1;i <= n;i++){
memset(vis,0,sizeof(vis));
for(int j = 1;j <= n;j++){
cin >> a[i][j];
if(a[i][j] >= 10 || a[i][j] <= 0){ //判断输入是否合法
f = 0;
continue; //防止在下面越界访问
}
if(vis[a[i][j]])f = 0; //判断每一行是否合法
else vis[a[i][j]] = 1;
}
}
if(f){
//判断每一列是否合法
for(int j = 1;j <= n;j++){
memset(vis,0,sizeof(vis));
for(int i = 1;i <= n;i++){
if(vis[a[i][j]])f = 0;
else vis[a[i][j]] = 1;
}
}
}
if(f){
//判断每一宫格是否合法
for(int g = 0;g < n;g++){
memset(vis,0,sizeof(vis));
for(int i = gp[g / 3][0];i <= gp[g / 3][1];i++){
for(int j = gp[g % 3][0];j <= gp[g % 3][1];j++){
if(vis[a[i][j]]) f = 0;
else vis[a[i][j]] = 1;
}
}
}
}
if(f)cout << "1" << endl;
else cout << "0" << endl;
}
int main(){
int t;cin >> t;
while(t--){
solve();
}
return 0;
}
L2 部分
L2 - 1 鱼与熊掌
L2-049 鱼与熊掌 - 团体程序设计天梯赛-练习集 (pintia.cn)
易错:map或者set会超时
思路:一个unordered_map存一个人所持有的物品,然后暴力。。
#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
const int N = 1e5 + 12;
unordered_map<int,int> a[N];
int main(){
int n,m;cin >> n >> m;
for(int i = 1;i <= n;i++){
int k;cin >> k;
for(int j = 0;j < k;j++){
int t;cin >> t;
a[i][t] = 1;
}
}
int q;cin >> q;
for(int i = 0;i < q;i++){
int t1,t2;cin >> t1 >> t2;
int res = 0;
for(int j = 1;j <= n;j++){
if(a[j].count(t1) && a[j].count(t2))res++;
}
cout << res << endl;
}
return 0;
}
L2 - 2 懂蛇语
L2-050 懂蛇语 - 团体程序设计天梯赛-练习集 (pintia.cn)
易错:1.字典中的句子可能以空格开头。
2.字典中可能会有相同的句子。
思路:map<字典句子中每个字的首字母组成的字符串,句子的vector数组>,
及map<string,vector<string>>
#include<iostream>
#include<vector> //不用set原因是会有相同的句子
#include<string>
#include<algorithm>
#include<cstdio>
#include<map>
using namespace std;
map<string, vector<string>> a;
string f(string str) { //获取句子每个字的首字母
string t;
if(str[0] != ' ')t.push_back(str[0]); //防止字典开头为空格
for (int i = 0; i < str.length() - 1; i++) {
if (str[i] == ' ' && str[i + 1] != ' ')t.push_back(str[i + 1]);
}
return t;
}
int main() {
int n; cin >> n;getchar();
for (int i = 1; i <= n; i++) {
string tem;
getline(cin, tem);
string t = f(tem);
a[t].push_back(tem);
}
int q; cin >> q;getchar();
while(q--){
string tem; getline(cin, tem);
string t = f(tem);
if (a.count(t)) { //看看字典中是否存在相应的句子
string res;
sort(a[t].begin(), a[t].end()); //排序不能忘
for (auto j : a[t]) {
res = res + j + "|";
}
res.pop_back();
cout << res << endl;
}
else cout << tem << endl;
}
return 0;
}
L2 - 3 满树的遍历
L2-051 满树的遍历 - 团体程序设计天梯赛-练习集 (pintia.cn)
易错:1.不能用链式前向星
2.当树中只有一个节点时,树的度为0
思路:用邻接表存树,从0开始dfs,存树时记录每个节点的度,找出最大的度,dfs时根据节点的度与最大度来判断是不是k阶满树。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 1e5 + 12;
int du[N];
vector<int> tree[N];
vector<int> res;
int deep,mdu;
int f = 1;
void dfs(int u){
if(u != 0 && mdu != tree[u].size() && du[u] != 0)f = 0;
res.push_back(u); //先序存入当前访问节点
for(int i = 0 ;i < tree[u].size();i++){
int v = tree[u][i];
dfs(v);
}
}
int main(){
int n;cin >> n;
for(int i = 1;i <= n;i++){
int t;cin >> t;tree[t].push_back(i);
du[t]++;
mdu = max(mdu,du[t]);
}
dfs(0);
if(n == 1)cout << "0 "; //如果树中只有一个节点,那么度为0
else cout << mdu << " ";
if(f)cout << "yes" << endl;
else cout << "no" << endl;
for(int i = 1;i < res.size();i++){
cout << res[i] << " \n"[i == res.size() - 1];
}
return 0;
}
L2 - 4 吉利矩阵
L2-052 吉利矩阵 - 团体程序设计天梯赛-练习集 (pintia.cn)
思路:模拟填表,搜索枚举所有可能。
#include<iostream>
using namespace std;
const int N = 5;
int a[5][5]; //填表 a[行][列]
int l, n, cnt;
int cheakrow(int x) { //检查行,求第x行的和
int sum = 0;
for (int i = 0; i < n; i++)sum += a[x][i];
return sum;
}
int cheakcol(int x) { //检查列,求第x列的和
int sum = 0;
for (int i = 0; i < n; i++)sum += a[i][x];
return sum;
}
void dfs(int x,int y) {
if (x == n - 1 && y == n - 1) {
cnt++; //填表完成后记录
return;
}
//一行一行地填表格
int dy = (y + 1) % N, dx = x + (y + 1) / N;
//枚举表格中的所有可能
for (int i = 0; i <= l; i++) {
//边界检查
if (y == n - 1 && cheakrow(x) + i != l)continue; //x行填满,检查第x行
if (x == n - 1 && cheakcol(y) + i != l)continue; //y列填满,检查第y列
//剪枝
if (cheakcol(y) + i > l || cheakrow(x) + i > l)break;
a[x][y] += i;
dfs(dx, dy);
a[x][y] -= i; //回溯
}
}
int main() {
cin >> l >> n;
dfs(0, 0);
cout << cnt << endl;
return 0;
}
L3部分
L3 - 1 夺宝大赛
L3-037 夺宝大赛 - 团体程序设计天梯赛-练习集 (pintia.cn)
思路:以终点为起点,做bfs,并把各个位置到起点的距离记录下来,根据队员的坐标直接提取最短距离并记录下来,最后根据规定去输出结果
易错:1.坐标输入时要反一下
2.bfs 对于标记的距离的时机有要求
曾尝试IDS但超时了...
#include<iostream>
#include<queue>
#include<map>
#include<vector>
#include<cstring>
using namespace std;
const int N = 123;
int a[N][N];
int vis[N][N];
int n, m, ex, ey;
int d[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
struct node { int x, y, t; };
map<int, vector<int>> res; //map<到大本营的时间,该时间时到达的队伍编号>
int bfs(node s) {
queue<node> q;
q.push(s);
vis[s.x][s.y] = s.t;
while (!q.empty()) {
node u = q.front(); q.pop();
//在此处记录距离会导致同一个节点重复入队多次而导致内存超限
//vis[u.x][u.y] = u.t;
for (int i = 0; i < 4; i++) {
int dx = u.x + d[i][0], dy = u.y + d[i][1];
if (dx < 1 || dy < 1 || dx > m || dy > n || a[dx][dy] == 0 || vis[dx][dy])continue;
vis[dx][dy] = u.t + 1; //在这里记录就可以避免内存超限
q.push(node{ dx,dy,u.t + 1 });
}
}
return -1;
}
int main() {
cin >> m >> n;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
if (a[i][j] == 2)ex = i, ey = j; //找大本营的位置
}
}
bfs(node{ ex,ey,1 });
for (int i = 1; i <= m; i++) { //把走不到的地方标记为-1
for (int j = 1; j <= n; j++) {
if (vis[i][j] == 0 && a[i][j] != 2)vis[i][j] = -1;
}
}
int k; cin >> k;
for (int i = 1; i <= k; i++) {
int x, y; cin >> y >> x; //这里要颠倒一下,仔细读题就会知道原因了
int t = vis[x][y];
if (t != -1) res[t - 1].push_back(i); 由于实际t是从1开始记录的,所以这里减一
}
for (auto i : res) {
if (i.second.size() == 1) {
cout << i.second[0] << " " << i.first << endl;
return 0;
}
}
cout << "No winner." << endl;
return 0;
}
L3 - 2 工业园区建设
L3-038 工业园区建设 - 团体程序设计天梯赛-练习集 (pintia.cn)
孩子正在补题....
L3 - 3 攀岩
L3-039 攀岩 - 团体程序设计天梯赛-练习集 (pintia.cn)
——题目过长无法展示——
孩子正在补题...