Codeforces Round 898 (Div. 4)(A~H)

目录

A. Short Sort

B. Good Kid

C. Target Practice

D. 1D Eraser

E. Building an Aquarium

F. Money Trees

G. ABBC or BACB

H. Mad City


A. Short Sort

Problem - A - Codeforces

暴力枚举每个位置的交换即可。

#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<cstring>
#include<set>
#include<map>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 1000010;
const int M = 1e9 + 7;
const int bit=63;
inline void solve() {
	string s;
	cin>>s;
	if(s=="abc")
	{
		cout<<"YES\n";
		return ;
	}
	for(int i=0;i<3;i++)
	{
		for(int j=i+1;j<3;j++)
		{
			string t=s;
			swap(t[i],t[j]);
			if(t=="abc")
			{
				cout<<"YES\n";
				return;
			}
		}
	}
	cout<<"NO\n";
}
signed main() {
	TEST
	solve();
	return 0;
}

B. Good Kid

Problem - B - Codeforces

将最小的数加上1,再全部相乘就是答案。

#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<cstring>
#include<set>
#include<map>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 1000010;
const int M = 1e9 + 7;
const int bit=63;
inline void solve() {
	int n;
	cin>>n;
	int a[n+1];
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+1+n);
	int ans=1;
	a[1]++;
	for(int i=1;i<=n;i++)
	{
		ans*=a[i];
	}
	cout<<ans<<"\n";
}
signed main() {
	TEST
	solve();
	return 0;
}

C. Target Practice

Problem - C - Codeforces

经典的if语句判断。

#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<cstring>
#include<set>
#include<map>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 1000010;
const int M = 1e9 + 7;
const int bit=63;
inline void solve() {
	char x;
	int ans=0;
	for(int i=1;i<=10;i++)
	{
		for(int j=1;j<=10;j++)
		{
			cin>>x;
			if(x=='X')
			{
				if(i>=5&&i<=6&&j>=5&&j<=6) 
				{
					ans+=5;
				}
				else if(i>=4&&i<=7&&j>=4&&j<=7)
				{
					ans+=4;
				}
				else if(i>=3&&i<=8&&j>=3&&j<=8)
				{
					ans+=3;
				}
				else if(i>=2&&i<=9&&j>=2&&j<=9)
				{
					ans+=2;
				}
				else ans++;
				
				
			}
		}
	}
	cout<<ans<<"\n";
}
signed main() {
	TEST
	solve();
	return 0;
}

D. 1D Eraser

Problem - D - Codeforces

从头枚举,找到B的位置,答案加一,从这开始的前k-1个位置的B不用给答案+1。

#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<cstring>
#include<set>
#include<map>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 1000010;
const int M = 1e9 + 7;
const int bit=63;
inline void solve() {
	int n,k;
	cin>>n>>k;
	string s;
	cin>>s;
	int ans=0,cnt=0;
	for(int i=0;i<n;i++){
		cnt--;
		if(s[i]=='B'&&cnt<=0)
		{
			ans++;
			cnt=k;
		}
	}
	cout<<ans<<"\n";
}
signed main() {
	TEST
	solve();
	return 0;
}

E. Building an Aquarium

Problem - E - Codeforces

经典的二分答案,都是有一个坑,就是r要开你比你想的大一些。

#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<cstring>
#include<set>
#include<map>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 1000010;
const int M = 1e9 + 7;
const int bit=63;
int a[N];
int n,x;
bool check(int xx)
{
	int sum=0;
	for(int i=1;i<=n;i++) sum+=max(0ll,xx-a[i]);
	
	return sum<=x;
}
inline void solve() {

	cin>>n>>x;
	for(int i=1;i<=n;i++) cin>>a[i];
	
	int L=1,R=1e12,ans;
	
	while(L<=R)
	{
		int mid=L+R>>1;
		if(check(mid)) 
		{
			ans=mid;
			L=mid+1;
		}
		else R=mid-1; 
 	}
	
	cout<<ans<<"\n";
}
signed main() {
	TEST
	solve();
	return 0;
}

F. Money Trees

Problem - F - Codeforces

也是一道二分答案的题,不过也可以贪心加双指针解决,这里给出两份代码。

二分答案:

#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<cstring>
#include<set>
#include<map>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 1e9 + 7;
const int bit = 63;
int sum[N], h[N], a[N];
int n, k;
vector<pair<int, int>>f;

bool check(int x)
{
	for(int i=0;i<f.size();i++)
	{
		if(f[i].second-f[i].first+1<x) continue;
		for(int j=f[i].first;j<=f[i].second-x+1;j++)
		{
			if(sum[j+x-1]-sum[j-1]<=k) return true;
		}
	}
	return false;
}
inline void solve() {
	f.clear();
	
	cin >> n >> k;

	for (int i = 1; i <= n; i++) cin >> a[i], sum[i] = sum[i - 1] + a[i];

	for (int i = 1; i <= n; i++) cin >> h[i];

	if(n==1)
	{
		if(a[1]>k)
		{
			cout<<0<<"\n";
		}
		else
		{
			cout<<1<<"\n";
			
		}
		return;
	}
	int l, r;
	l = r = 1;
	for (int i = 2; i <= n; i++) {
		if (h[i - 1] % h[i] == 0) {
			r++;
		} else {
			f.push_back({l,r});
			l = r = i;
		}
	}
	
	f.push_back({l,r});
	
	l=1,r=N;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(check(mid)) 
		{
			l=mid+1;
		}
		else r=mid-1;
	}
	cout<<r<<"\n";
	
}
signed main() {
	TEST
	solve();
	return 0;
}

贪心+双指针:

#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<cstring>
#include<set>
#include<map>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 1000010;
const int M = 1e9 + 7;
const int bit = 63;
int sum[N], a[N], h[N];
inline void solve() {
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++) cin >> a[i], sum[i] = sum[i - 1] + a[i];
	for (int i = 1; i <= n; i++) cin >> h[i];
	int mx = 0;
	int l = 1, r = 1;
	while(r<=n)
	{
		if(h[r-1]%h[r]) l=r;
		while(sum[r]-sum[l-1]>k) l++;
		mx=max(mx,r-l+1);
		r++;
	}
	cout<<mx<<"\n";
}
signed main() {
	TEST
	solve();
	return 0;
}

G. ABBC or BACB

Problem - G - Codeforces

先是模拟了一个,发现用贪心就可以解决。

找到所有的连续A段,再找到字符串元素B的个数。将每个A段按照长度从大到小排序,每个A短对应一个元素B,答案加上A段的长度,最后得到答案。

#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<cstring>
#include<set>
#include<map>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 1000010;
const int M = 1e9 + 7;
const int bit = 63;
struct node {
	int l, r;
} e[N];
bool cmp(node a,node b)
{
	return a.r-a.l>b.r-b.l;
}
inline void solve() {
	string s;
	cin >> s;
	int n = s.size();
	s = '#' + s;

	int l = -1, r, c = 0,B=0;
	for (int i = 1; i <= n; i++) {
		if(s[i]=='B') B++;
		
		if (s[i] == 'A' && l == -1) {
			l = i;
			r = i;
		} else if (s[i] == 'A' && l != -1) {
			r++;
		} else {
			if (l != -1) {
				e[++c].l = l;
				e[c].r = r;
				l = -1;
			}
		}
	}
	if (l != -1) {
		e[++c].l = l;
		e[c].r = r;
		l = -1;
	}
	
	sort(e+1,e+1+c,cmp);
	
	int ans=0;
	
	for(int i=1;i<=c;i++)
	{
		if(B==0) break;
		ans+=(e[i].r-e[i].l+1);
		B--;
	}
	
	cout<<ans<<"\n";
}
signed main() {
	TEST
	solve();
	return 0;
}

H. Mad City

Problem - H - Codeforces

题目给出限制,每两个顶点最多有一条边相连,有n条边n个顶点,那么就必成一个环,我们要找到的是b到环中最近的一个顶点叫做入环点。我们需要判断b到入环点的距离严格小于a到入环点的距离。

第一步:

找入环点,如果b已经在一个环中,那么它本身就是入环点,反之从b开始搜索,遍历过的点标记,当遍历到一个已经遍历过的点,并且这个点不是它的父节点,那么这个点就是入环点。

第二步:找a和b到入环点的最短路径。

b的最短路径小于a的最短路径,则输出"YES"反之输出"NO"。

#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<cstring>
#include<set>
#include<map>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 1e9 + 7;
const int bit = 63;
int n, a, b, huan = -1, vis[N];
vector<int>f[N];
bool dfs(int u, int p) {
	vis[u] = true;
	for (auto v : f[u]) {
		if (v != p && vis[v]) {
			huan = v;
			return true;
		} else if (v != p && !vis[v]) {
			if (dfs(v, u)) {
				return true;
			}
		}
	}
	return false;
}
void bk() {
	for (int i = 1; i <= n; i++) {
		f[i].clear();
	}
}
int ans1 = 1e9, ans2 = 1e9;
int dfs2(int u)
{
    vis[u] = 1;
    int ans = 1e9;
    for(auto v : f[u])
    {
        if(v == huan)
        {
            return 1;
        }
        if(!vis[v])
        {
            int dist = dfs2(v)+1;
            ans = min(dist, ans);
        }
    }
    return ans;
}
inline void solve() {
	bk();
	ans1 = 1e9, ans2 = 1e9;
	cin >> n >> a >> b;
	huan = -1;
	for (int i = 1; i <= n; i++) {
		int u, v;
		cin >> u >> v;
		f[u].push_back(v);
		f[v].push_back(u);
	}
	if (n == 3 && a != b) {
		cout << "YES\n";
		bk();
		return;
	}
	if (a == b) {
		cout << "NO\n";
		bk();
		return;
	}
	//标记成环点
	memset(vis, 0, sizeof(vis));
	dfs(b, -1);
	memset(vis, 0, sizeof(vis));
	if (b == huan) {
		ans1 = 0;
	} else
		ans1 = dfs2(b);
	memset(vis, 0, sizeof(vis));
	if (a == huan) {
		ans2 = 0;
	} else
		ans2 = dfs2(a);
	if (ans1 < ans2) {
		cout << "YES\n";
		return;
	} else {
		cout << "NO\n";
		return ;
	}
	bk();
}
signed main() {
	TEST
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值