【天梯赛训练记录】GPLT 团体程序设计天梯赛训练2
训练情况

赛后反思
差点被大模拟创死了,居然调出来了,后序遍历转层序遍历差点没做出来,最后几分钟极限过的,图论还需要加强
L1-1
签到题
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
cout<<"Talk is cheap. Show me the code.";
}
L1-2
签到题,体积是长x宽x高
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int a,b,c; cin>>a>>b>>c;
cout<<a*b*c;
}
L1-3
这题考阅读理解,对于固体流体分类讨论,比较两个数的大小判断即可
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
double a,c; int b;
cin>>a>>b>>c;
if(b == 1){
double x = a*1.26;
cout<<fixed<<setprecision(2)<<x<<" ";
if(x<=c) cout<<"^_^"<<endl;
else cout<<"T_T"<<endl;
} else {
double x = a*2.455;
cout<<fixed<<setprecision(2)<<x<<" ";
if(x<=c) cout<<"^_^"<<endl;
else cout<<"T_T"<<endl;
}
}
L1-4
签到题,倒数求和再倒数
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int n; cin>>n;
vector<double> a(n + 1);
double sum = 0;
for(int i = 1;i<=n;i++) cin>>a[i],sum += 1.0/a[i];
cout<<fixed<<setprecision(2)<<1.0/(sum/n);
}
L1-5
稍微复杂一点的模拟题,我们需要先求胎压的最大值,统计是否误差超过阈值的个数,分类即可,只有一个就输出那个位置,大于一个就需要检查全部的轮胎
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int a[4],b,c;
int ma = 0;
for(int i = 0;i<4;i++) cin>>a[i],ma = max(ma,a[i]); cin>>b>>c;
bool flag = true;
int cnt = 0;
int pos = 0;
for(int i = 0;i<4;i++){
if(!(abs(a[i] - ma) <= c && a[i] >= b)) pos=i,flag = false,cnt++;
}
if(flag){
cout<<"Normal"<<endl;
return 0;
}
if(cnt>1){
cout<<"Warning: please check all the tires!"<<endl;
return 0;
}
cout<<"Warning: please check #"<<pos+1<<"!"<<endl;
}
L1-6
求字符串是否包含 chi1 huo3 guo1,对于含有空格的字符串我们使用getline进行输入,当某一行只有 . 的时候退出循环,我们使用string的STL中的substr求子串,判断是否出现并统计个数和第一个出现的位置即可
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
int cnt = 0;
vector<int> ans;
while(1){
getline(cin,s);
if(s == ".") break;
cnt++;
for(int i = 0;i+13<s.size();i++){
if(s.substr(i,14) == "chi1 huo3 guo1"){
ans.emplace_back(cnt);
break;
}
}
}
cout<<cnt<<endl;
if(ans.size() == 0){
cout<<"-_-#"<<endl;
return 0;
}
cout<<ans[0]<<" "<<ans.size()<<endl;
}
L1-7
考察二叉树的表示方法,左子树 \(\times 2\),右子树 \(\times 2 + 1\),我们直接求叶子结点的编号即可,最后需要减掉非叶子结点的编号即可
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
int n,m; cin>>n>>m;
while(m--){
int ans = 1;
string s; cin>>s;
for(int i = 0;i<n;i++){
if(s[i] == 'y') ans*=2;
else if(s[i] == 'n') ans = ans*2 + 1;
}
cout<<(int)(ans-pow(2ll,n)+1)<<endl;
}
}
L1-8
有点恶心的模拟题,我们提前把数字对应的金币存到数组里,已知八个数,先把刮掉的那个数找出来,按照题目三行三竖两斜统计数字和,输出对应金币即可,难在分类讨论和代码实现
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
int n = 3;
vector<vector<int>> a(n + 1,vector<int>(n + 1));
vector<vector<bool>> vis(n + 1,vector<bool>(n + 1));
vector<bool> v(30);
vector<int> ans(30);
ans[6] = 10000; ans[7] = 36; ans[8] = 720; ans[9] = 360; ans[10] = 80;
ans[11] = 252; ans[12] = 108; ans[13] = 72; ans[14] = 54; ans[15] = 180;
ans[16] = 72; ans[17] = 180; ans[18] = 119; ans[19] = 36; ans[20] = 306;
ans[21] = 1080; ans[22] = 144; ans[23] = 1800; ans[24] = 3600;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
cin>>a[i][j];
v[a[i][j]] = 1;
if(a[i][j] == 0) vis[i][j] = 1;
}
}
int d;
for(int i = 1;i<=9;i++) if(!v[i]) d = i;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
if(a[i][j] == 0) a[i][j] = d;
}
}
for(int i = 1;i<=n;i++){
int x,y; cin>>x>>y;
cout<<a[x][y]<<endl;
vis[x][y] = 1;
}
int opt; cin>>opt;
int now = 0;
if(opt >= 1 && opt <= 3){
for(int i = 1;i<=3;i++) now += a[opt][i];
} else if(opt >= 4 && opt <= 6){
for(int i = 1;i<=3;i++) now += a[i][opt-3];
} else if(opt == 7){
for(int i = 1;i<=3;i++) now += a[i][i];
} else if(opt == 8){
for(int i = 1;i<=3;i++) now += a[i][n-i+1];
}
cout<<ans[now]<<endl;
}
L2-1
白送的后缀表达式,我们开两个栈,一个栈存符号,一个栈存数字,每次从数字栈中取出两个,符号栈取一个,运算完再塞回数字的栈(注意一下除法除数为零特判),一直循环到数字栈内只剩下一个就直接输出即可。
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
stack<int> a; stack<char> b;
int n; cin>>n;
for(int i = 1;i<=n;i++){
int x; cin>>x;
a.push(x);
}
for(int i = 1;i<n;i++){
string s; cin>>s;
b.push(s[0]);
}
while(a.size() >= 2){
int y = a.top(); a.pop();
int x = a.top(); a.pop();
// cout<<x<<" "<<y<<endl;
char s = b.top(); b.pop();
if(s == '+'){
a.push(x+y);
} else if(s == '-'){
a.push(x-y);
} else if(s == '*'){
a.push(x*y);
} else if(s == '/'){
if(y == 0){
cout<<"ERROR: "<<x<<"/0"<<endl;
return 0;
}
a.push(x/y);
}
}
cout<<a.top()<<endl;
}
L2-2
超级无敌巨恶心的大模拟题,我们首先开一个结构体记录人的基本信息,首先判断身份证号是否合法,再将输入的时间处理一下,转换成分钟*60+秒钟,之后排序优先按照时间其次是顺序进行排序,再需要记录一下某一个人上一次拿到口罩的天数,判断是否能不能再拿,最后统计身份证号合法且健康情况异常的人(注意一下重复的问题,这里另开一个数组表示是否已经记录过),难点在代码实现和调试上
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int d,p;
map<string,int> last;
struct node{
int no;
int pos;
string name,sfz;
int zk;
int t;
};
vector<node> gg;
map<string,bool> in;
bool cmp(node x,node y){
if(x.t == y.t) return x.pos < y.pos;
else return x.t < y.t;
}
signed main(){
cin>>d>>p;
for(int day = 1;day<=d;day++){
int t,s; cin>>t>>s;
vector<node> a(t + 1);
for(int i = 1;i<=t;i++){
a[i].no = 0;
a[i].pos = i;
cin>>a[i].name>>a[i].sfz>>a[i].zk;
if(a[i].sfz.size() != 18) a[i].no = 1;
for(int j = 0;j<a[i].sfz.size();j++) if(!(a[i].sfz[j] >= '0' && a[i].sfz[j] <= '9')) a[i].no = 1;
if(!last[a[i].sfz])last[a[i].sfz] = -100;
string tmp; cin>>tmp;
int h,m; sscanf(tmp.c_str(),"%lld:%lld",&h,&m);
a[i].t = h*60+m;
if((!a[i].no) && a[i].zk == 1 && !in[a[i].sfz]) gg.emplace_back(a[i]),in[a[i].sfz]=1;
}
sort(a.begin() + 1,a.begin() + 1 + t,cmp);
int cnt = 0;
for(int i = 1;i<=t;i++){
if(cnt==s) break;
if(a[i].no) continue;
if(day - last[a[i].sfz] < p+1) continue;
last[a[i].sfz] = day;
cout<<a[i].name<<" "<<a[i].sfz<<endl;
cnt++;
}
}
for(int i = 0;i<gg.size();i++){
cout<<gg[i].name<<" "<<gg[i].sfz<<endl;
}
}
L2-3
后序遍历转正常的存树方法,后序遍历按照左右根的顺序,递归下去还原树的结构,之后层序遍历使用 BFS 一层层输出即可,这题23队长还有一个做法就是后序遍历翻转变成根右左的方式,还原二叉树,直接按照顺序输出下去就是层序遍历了
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 40;
int n,lim;
int diff;
int a[N];
int t[N*2];
int tot;
void dfs(int x,int dep){
if(x>=pow(2,lim)-diff) return;
if(dep == lim){
t[x] = a[++tot];
return;
}
if(dep < lim) dfs(x*2,dep + 1);
if(dep < lim) dfs(x*2 + 1,dep + 1);
t[x] = a[++tot];
}
int main(){
cin>>n;
for(int i = 1;i<=n;i++) cin>>a[i];
for(int i = 0;i<=30;i++){
if(pow(2,i) > n){
lim = i;
break;
}
}
diff = (pow(2,lim) - 1) - n;
// cout<<diff<<endl;
// cout<<lim<<endl;
dfs(1,1);
queue<int> q;
q.push(1);
vector<int> ans;
while(q.size()){
int x = q.front(); q.pop();
ans.emplace_back(t[x]);
if(t[x*2]) q.push(x*2);
if(t[x*2+1]) q.push(x*2+1);
}
for(int i = 0;i<ans.size();i++){
if(i == ans.size() - 1) cout<<ans[i];
else cout<<ans[i]<<" ";
}
return 0;
}

浙公网安备 33010602011771号