atcoder ABC373 题解
首先说一下,本人小学,制作了四题,如果你AC>4题(你也可以看看)。支持一下我把呜呜呜。
A.September
就给你12个字符串,问你有多少个字符串它的长度与位置相等,第一个位置是一,第二个是二,以此类推。
思路:模拟,
看看那些符合条件,用累加器加一即可。
附上代码:
#include <bits/stdc++.h>
using namespace std;
string a;//表示字符串
int ans;//累加器
signed main(){
for(int i=0;i<12;i++){
cin>>a;
if(a.size()==i+1)ans++;//符合条件累加器加一
}
cout<<ans;
return 0;
}
B.1D Keyboard
给你一个键盘,键盘不规则,但一定是26个英文大写字母的排列。用这个键盘从‘A’打到‘Z’,问移动了多少次,一开始在‘A’键上。
思路:模拟,记录每一个字母再键盘上的位置,打字时,用一个变量记录打的上一个字母的位置,用现在要打的键的位置减去上一个,得到移动多少格,另外,移动的格数需要进行绝对值操作。
代码:
#include <bits/stdc++.h>
using namespace std;
string a;
int last,ans;//last是上一个字母的位置,ans是最后的答案。
map<char,int> s;//记录‘A’到‘Z’在键盘上的位置。
signed main(){
cin>>a;
for(int i=0;i<a.size();i++)
s[a[i]]=i+1;//记录位置
last=s['A'];//一开始last就是A的位置
for(char x='B';x<='Z';x++){
ans+=abs(s[x]-last);//计算移动格数
last=s[x];//更新last
}
cout<<ans;
return 0;
}
C.Max Ai+Bj
给定长度相同的两个数组,求个选一个数的最大和。
思路:暴力TLE,考虑贪心,双方最大值相加一定最优 。
代码:
#include <bits/stdc++.h>
using namespace std;
const int INF=-1e9-7;
int n,x,mx1=INF,mx2=INF;//mx1,mx2分别表示两个最大值
signed main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>x;
mx1=max(mx1,x);//求第一个
}
for(int i=0;i<n;i++){
cin>>x;
mx2=max(mx2,x);//求第二个
}
cout<<mx1+mx2;//输出
return 0;
}
给定一颗有向图,对于每个点求一个值(点x用f(x)表示),满足每条x->y,边权为k的有向边。。求其中一个可行解。
思路:如果出现x->y<-z这种情况,需要从两个方向遍历,可能会出现求出的值不同的情况,为了处理,需要重置一个方向的值,时间复杂度O(n*n),需优化。可以发现,对于一条边,以下公式必须成立。,这样,无论怎么遍历,都可以正确求值。对于冲突情况,就无需从两个方向遍历,也就是转换成了无向图。细节:可能不连通。
代码:
#include <bits/stdc++.h>
#define st first
#define nd second
#define MP make_pair
#define int long long
#define allx(a) a.begin(),a.end()
#define ally(a) a.rbegin(),a.rend()
using namespace std;
const int N=3e5,dx[4]={0,0,-1,1};
const int INF=1000000000000000005,mod=1000000007;
int v,e,lx,ly,lz,ans[N];//ans数组表示答案
bool used[N];//是否遍历
vector<pair<int,int> > G[N];//存图(用无向图存)
void dfs(int x){
used[x]=1;//标记出现
for(int i=0;i<G[x].size();i++){
if(!used[G[x][i].st]){//判断是否走过
ans[G[x][i].st]=ans[x]+G[x][i].nd;//松弛
dfs(G[x][i].st);//递归
}
}
}
signed main(){
cin>>v>>e;
for(int i=0;i<e;i++){
cin>>lx>>ly>>lz;
G[lx].push_back(MP(ly,lz));//正向时不改变
G[ly].push_back(MP(lx,-lz));//反建时,根据公式,边权取反
}
for(int i=1;i<=v;i++){
if(!used[i])//如果没有遍历
dfs(i);
}
for(int i=1;i<=v;i++)cout<<ans[i]<<" ";
return 0;
}
e题没想出来寄。完结散花。