- 伍衍 的博客
DAY4
- @ 2024-7-11 18:36:21
考试错误:一遍的,没有错误。
思路:
只有三种运算可以达到最大值:··,(+)·,++,取最大值即可。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=4;
int a[N];
signed main(){
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
int a,b,c;
cin >> a >> b >> c;
cout << max(a*b*c,max((a+b)*c,a+b+c))
return 0;
}
错误原因:只想到了一半,骗分的,没错误。
思路:
输出和最接近×的的倍数((×)/×)。它们的和与差一定大于,.
代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
freopen("gcd.in","r",stdin);
freopen("gcd.out","w",stdout);
long long x,y,z;
cin >> x >> y >> z;
cout << z << " " << (long long)(5000000000000000000/z*z);
}
错误原因:暴力做的,骗了一半分,没有错误。
不会做原因:对双指针的理解不深刻。
思路:
.用前缀和简化区间和。
.双指针算法:从到-,初始为。
.如果[]>=[]-[],那么break;
.接着while(s[j]-s[i]<=s[i]||s[j]-s[i]<=s[n]-s[j]) j++,寻找山峰数组。
.最后让cnt+=n-j;一次性找出多个山峰数组(线性复杂度的关键)。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+50;
int a[N],s[N];
signed main(){
freopen("mountain.in","r",stdin);
freopen("mountain.out","w",stdout);
int n;
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
s[i]=s[i-1]+a[i];
}
int cnt=0;
for(int i=1,j=2;i<n-1;i++){
if(s[i]>=s[n]-s[i]) break;
while(s[j]-s[i]<=s[i]||s[j]-s[i]<=s[n]-s[j]) j++;
cnt+=n-j;
}
cout << cnt;
}
未做出原因:没有时间了,下一次要提高做题速度,尽量不空题。
思路:
.用两个队列,统计两个阵营人所在的位置。
.比较队首元素,顺序靠前的就复制一份到队尾,随后同时pop()。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int hh1=0,tt1=-1,hh2=0,tt2=-1;
int r[10020],d[10020];
signed main(){
freopen("dota.in","r",stdin);
freopen("dota.out","w",stdout);
int t;
cin >> t;
while(t--){
hh1=0,tt1=-1,hh2=0,tt2=-1;
string s;
cin >> s;
int n=s.size();
for(int i=0;i<n;i++){
if(s[i]=='R') r[++tt1]=i;
else d[++tt2]=i;
}
while(hh1<=tt1&&hh2<=tt2){
if(r[hh1]<d[hh2]) r[++tt1]=r[hh1]+n;
else d[++tt2]=d[hh2]+n;
hh1++;
hh2++;
}
if(hh2>tt2) cout << "Radiant\n";
else cout << "Dire\n";
}
}
考试错误:一遍的,没有错误。
思路:
BFS裸题,过于简单,思路自己看讲义,这里省略。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct P{
int x,y,step;
};
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
queue<P> q;
int vis[50][50],mp[50][50];
int n,m,s1,s2,b1,b2;
void bfs(){
vis[s1][s2]=1;
q.push(P{s1,s2,0});
while(q.size()){
P now=q.front();
q.pop();
if(now.x==b1&&now.y==b2){
cout << now.step;
return;
}
for(int i=0;i<4;i++){
int nx=now.x+dx[i],ny=now.y+dy[i];
if(nx<1||nx>n||ny<1||ny>m) continue;//越界
if(vis[nx][ny]||mp[nx][ny]) continue;//不能走
q.push(P{nx,ny,now.step+1});
vis[nx][ny]=1;
}
}
cout << -1;
return;
}
signed main(){
freopen("mg.in","r",stdin);
freopen("mg.out","w",stdout);
cin >> n >> m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
char c;
cin >> c;
if(c=='.') mp[i][j]=0;
if(c=='#') mp[i][j]=1;
if(c=='@') s1=i,s2=j;
if(c=='*') b1=i,b2=j;
}
}
bfs();
}
未做出原因:最短路没有学好,导致背不出的模版。
思路:
模板题,只有起点位置和终点位置变了,背下来就会。
代码:
#include <bits/stdc++.h>
using namespace std;
int arr[1005][1005];
int dist[1005];
bool v[1005];
int n,m,ans,e,s;
int dijkstra(){
memset(dist,0x3f,sizeof(dist));
memset(v,0,sizeof(v));
dist[e]=0;
for (int i=1;i<n;i++){
int x=-1;
for(int j=1;j<=n;j++){
if(!v[j]&&(x==-1||dist[j]<dist[x])) x=j;
}
v[x]=1;
for(int y=1;y<=n;y++){
if(arr[x][y]!=0x3f3f3f3f&&dist[y]>dist[x]+arr[x][y]){
dist[y]=dist[x]+arr[x][y];
}
}
}
if(dist[s]==0x3f3f3f3f) return -1;
return dist[s];
}
int main(){
freopen("city.in","r",stdin);
freopen("city.out","w",stdout);
cin >> n >> m;
memset(arr, 0x3f, sizeof(arr));
for(int i=1;i<=n;i++)arr[i][i]=0;
for(int i=1;i<=m;i++){
int x,y,z;
cin >> x >> y >> z;
arr[x][y]=min(arr[x][y],z);
arr[y][x]=min(arr[y][x],z);
}
cin >> e >> s;
ans=dijkstra();
if(ans==-1) cout << "No path";
else cout << ans;
return 0;
}