前置
34s切A祭
[ABC325A] Takahashi san
题意简述
给定两个字符串
s
,
t
s,t
s,t,你需要输出字符串
s
s
s,并将
t
t
t 修改为 san
后输出,并在
s
s
s 和
t
t
t 之间输出一个空格。
解题思路
照着题目说的做就行。
代码示例
#include<bits/stdc++.h>
using namespace std;
string s,t;
int main(){
cin>>s>>t;
cout<<s<<" san"<<endl;
return 0;
}
[ABC325B] World Meeting
题意简述
现在有 n n n 个世界和一个基准世界,第 i i i 个世界中有 w i w_i wi 个人,比基准世界的时间快了 x i x_i xi 小时。现在你以基准世界的时间为基准,召开一个一小时的会议,显然其他世界中会议召开的时间会相应提前 x i x_i xi 小时。当且仅当整个会议时间对应到第 i i i 个世界后,在九点至十八点内,第 i i i 个世界的人会参加会议。你可以任意选定会议时间,但必须整点开始。问最多可以有多少人参加会议。
解题思路
枚举举办会议的时间,然后挨个扫有多少个世界的人能参加,取最大值。
代码示例
#include<bits/stdc++.h>
using namespace std;
int n,w[200010],x[200010];
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i]>>x[i];
int ans=0;
for(int i=0;i<=24;i++){
int num=0;
for(int j=1;j<=n;j++) if((x[j]+i)%24>=9&&(x[j]+i)%24<=17) num+=w[j];
ans=max(ans,num);
}
cout<<ans<<endl;
return 0;
}
[ABC325C] Sensors
题意简述
给定一个
n
×
m
n \times m
n×m的区域,若
s
i
,
j
s_{i,j}
si,j 为 #
,则
(
i
,
j
)
(i,j)
(i,j) 处有一个传感器。若一个传感器
A
A
A 周围八个格子中有另一个传感器
B
B
B,称它们为相邻的。传感器的相邻关系可以传递。所有相邻的传感器视作一个,问有多少个传感器。
解题思路
相当于求连通块的数量。注意一个传感器上下左右、左上、左下、右上、右下的传感器都视作联通的。
代码示例
#include<bits/stdc++.h>
using namespace std;
int n,m,vis[2010][2010],ans=0;
string s[200010];
int dx[20]={0,1,1,1,-1,-1,-1,0,0};
int dy[20]={0,0,1,-1,0,1,-1,1,-1};
void dfs(int x,int y){
vis[x][y]=1;
for(int i=1;i<=8;i++){
int tx=x+dx[i],ty=y+dy[i];
if(tx<1||ty<1||tx>n||ty>m) continue;
if(!vis[tx][ty]&&s[tx][ty]=='#') dfs(tx,ty);
}
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>s[i],s[i]=" "+s[i];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(s[i][j]=='#'&&!vis[i][j]) dfs(i,j),ans++;
}
}
cout<<ans<<endl;
return 0;
}
[ABC325D] Printing Machine
题意简述
给定 n n n 个球, 1 0 100 10^{100} 10100 个格子,第 i i i 个球需要放在 x i , x i + y i x_i,x_i+y_i xi,xi+yi 格子中的某一个。已经放过球的格子不能再放。问最多能放多少个球。
解题思路
首先考虑一种贪心策略。
对于格子 T = 1 , 2 , 3 … T=1,2,3… T=1,2,3…,若此时有球能放,取一个 x i + y i x_i+y_i xi+yi 最小的放进去。因为 x i + y i x_i+y_i xi+yi 更大的球有可能可以放在更后面,这一定比将它放在 T T T 更优。
但这样做会 TLE。考虑先将球对于 x i x_i xi 排个序, x i x_i xi 相同的按照 x i + y i x_i+y_i xi+yi 排序。我们在将 T T T 扫过去的过程中,很多格子其实都放不了球,白白浪费了时间。所以我们用一个优先队列 q q q 记录当前等待放入的球,如果 q q q 空了,就将 T T T 跳到下一个球的可放置的起始位置。
代码示例
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
vector<pair<int,int> > a;
priority_queue<int,vector<int>,greater<> > q;
signed main(){
cin>>n;
a.push_back({-1,0});
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
a.push_back({x,x+y});
}
sort(a.begin(),a.end());
int cnt=0,ans=0;
for(int T=1;;T++){
if(q.empty()){
if(cnt==n) break;
T=a[++cnt].first;
q.push(a[cnt].second);
}
while(cnt<=n-1&&a[cnt+1].first==T) q.push(a[++cnt].second);
while(!q.empty()&&q.top()<T) q.pop();
if(!q.empty()) ans++,q.pop();
}
cout<<ans<<endl;
return 0;
}
[ABC325E] Our clients, please wait a moment
题意简述
有 n n n 个城市和三个参数 A , B , C A,B,C A,B,C。给定一个 n × n n\times n n×n 的矩阵 D D D。从城市 i i i 到 j j j 有两种方式,坐车花费 D i , j × A D_{i,j}\times A Di,j×A 时间,坐高铁花费 D i , j × B + C D_{i,j}\times B + C Di,j×B+C 时间。一开始可以自由选择坐车还是坐高铁,但是如果某次选择坐高铁了,那么之后你只能选择坐高铁。
解题思路
感觉很典啊。建一个分层图跑 dijkstra 就可以了。第一个图 G 1 G1 G1 全部以坐车需要的时间为边权,第二个图 G 2 G2 G2 全部以坐高铁需要的时间为边权。因为坐车可以转坐高铁,所以 G 1 G1 G1 中每个点向 G 2 G2 G2 中对应的点连一条边权为 0 0 0 的边就好了。
代码示例
#include<bits/stdc++.h>
using namespace std;
int n,A,B,C;
int a[1010][1010];
struct node{
int v,w;
bool operator<(const node &b)const{
return w>b.w;
}
};
vector<node> G[200010];
int dis[200010];
void Dijkstra(){
dis[1]=0;
priority_queue<node> q;
q.push({1,0});
while(!q.empty()){
int u=q.top().v;
q.pop();
for(auto x:G[u]){
int v=x.v,w=x.w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push({v,dis[v]});
}
}
}
}
signed main(){
memset(dis,0x3f,sizeof(dis));
cin>>n>>A>>B>>C;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>a[i][j];
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
G[i].push_back({i+n,0});
G[i].push_back({j,A*a[i][j]});
G[i+n].push_back({j+n,B*a[i][j]+C});
}
}
Dijkstra();
cout<<min(dis[n],dis[n+n])<<endl;
return 0;
}