- 闫晟淏 的博客
暑假七月DAY8
- @ 2025-7-22 21:00:16
错题:
A
错因:
进制转换时未减一(做题时输出时减一,但应该进制转换时减一)
思路:
输入n,循环n每次减一并于栈a压入n%26+‘a’,n除26直到n=0 (这一步可以将n(10进制)变成26进制(存入栈a))之后把a从头到尾输出。
参考代码
#include<bits/stdc++.h>
using namespace std;
stack<char> a;
int main(){
freopen("dog.in","r",stdin);
freopen("dog.out","w",stdout);
long long n,cnt=0;
cin>>n;
while(n){
n--;
a.push(n%26+'a');
n/=26;
}
while(!a.empty()){
cout<<a.top();
a.pop();
}
return 0;
}
B
错因:
h与hi变量名混淆,以后在题目里遇到重名变量时一个后面加上1(如a,a1)。
易错点:
数组输入起始点要一致。
思路:
使用一维数组,将一组hi>0的数据放在第一位
循环枚举所有的cx和cy,之后,通过第一组数据算出h,对结果进行判断是否满足hi=max(h-|cx-xi|-|cy-yi|,0),不符合则直接换下一组数据,直到满足条件。
参考代码
#include<bits/stdc++.h>
using namespace std;
int x[103],y[103],h[103];
int n;
bool check(int a,int b,int hh){
for(int i=2;i<=n;i++){
if(max(hh-abs(a-x[i])-abs(b-y[i]),0)!=h[i]){
return false;
}
}
return true;
}
int main(){
freopen("tower.in","r",stdin);
freopen("tower.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i]>>y[i]>>h[i];
if(h[i]>0){
swap(x[i],x[1]);
swap(y[i],y[1]);
swap(h[i],h[1]);
}
}
for(int ax=0;ax<=100;ax++){
for(int ay=0;ay<=100;ay++){
int ah=h[1]+abs(x[1]-ax)+abs(y[1]-ay);
if(check(ax,ay,ah)){
cout<<ax<<' '<<ay<<' '<<ah<<endl;
return 0;
}
}
}
return 0;
}
C
错因:
考虑到是在比赛,写了后面好拿分的题目,导致没时间回来写了
思路:
循环枚举所有的起点与终点,然后用bfs算出最小的路径。(bfs在求最短路时不会超时)
参考代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
int op[110][110], vis[110][110], dist[110][110];
int dx[] = {0,1,0,-1}, dy[] = {1,0,-1,0};
void bfs(int sx,int sy,int ax,int ay){
queue<pair<int,int> > q;
q.push({sx,sy});
vis[sx][sy] = 1;
dist[sx][sy] = 0;
while (q.size()){
auto t=q.front();
q.pop();
int x=t.first,y=t.second;
if (x==ax &&y==ay) return;
for (int i=0;i<4;i++)
{
int nx=x +dx[i],ny=y+dy[i];
if (nx>=1&&nx<=n&&ny>=1&&ny<=m&&op[nx][ny]&&vis[nx][ny]==0){
vis[nx][ny] = 1;
q.push({nx, ny});
dist[nx][ny] = dist[x][y] + 1;
}
}
}
}
int main(){
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
cin >> n >> m;
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
char po;
cin>>po;
if(po=='.') op[i][j]=1;
}
}
int ans=0;
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
for (int i1=1;i1<=n;i1++){
for (int j1=1;j1<=m;j1++){
if(op[i][j]&&op[i1][j1]){
memset(dist, 0x3f, sizeof dist);
memset(vis,0, sizeof vis);
bfs(i,j,i1,j1);
ans=max(dist[i1][j1],ans);
}
}
}
}
}
cout<<ans<<endl;
return 0;
}
E(本题不涉及算法,学完语法的人也能做)
错因:
1.没想起来用multiset。(必须用才能AC,其在输入时可以自动排序,省下很多时间)(其不会去重) 2.因为手误将k写成了x,导致答案输出不正确。
思路:
使用循环,Q次输入x,x<=1e18(可能会爆int)要用long long,用multiset解决排序容易超时的问题,但一定要熟悉其用法,不然会容易出错(特别注意:end函数,其指向set的最后一位的后一位)
参考代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
int q;
multiset<ll> s;
int main(){
freopen("list.in","r",stdin);
freopen("list.out","w",stdout);
cin>>q;
while(q--){
ll a,x,k;
cin>>a;
if(a==1){
cin>>x;
s.insert(x);
}else if(a==2){
bool po=true;
cin>>x>>k;
auto it=s.upper_bound(x);
while(k--&&it!=s.begin()) it--;
if(k>=0||it==s.end()) po=false;
if(po) cout<<*it<<endl;
else cout<<-1<<endl;
}else{
bool po=true;
cin>>x>>k;
auto it=s.lower_bound(x);
k--;
while(k--&&it!=s.end()) it++;
if(it==s.end()) po=false;
if(po) cout<<*it<<endl;
else cout<<-1<<endl;
}
}
return 0;
}
THE END