atcoder abc 373 (A-D)

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;
}

D. Hidden Weights 

给定一颗有向图,对于每个点求一个值(点x用f(x)表示),满足每条x->y,边权为k的有向边。f(y)=f(x)+k。求其中一个可行解。

思路:如果出现x->y<-z这种情况,需要从两个方向遍历,可能会出现求出的值不同的情况,为了处理,需要重置一个方向的值,时间复杂度O(n*n),需优化。可以发现,对于一条边,以下公式必须成立。f(y)=f(x)+k,f(x)=f(y)-k,这样,无论怎么遍历,都可以正确求值。对于冲突情况,就无需从两个方向遍历,也就是转换成了无向图。细节:可能不连通。

代码:

#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题没想出来寄。完结散花。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值