首页 > 其他分享 >AtCoder Beginner Contest 267 ABCDE

AtCoder Beginner Contest 267 ABCDE

时间:2023-06-26 09:03:44浏览次数:51  
标签:AtCoder 题意 int ll ABCDE long 267 Statement using

AtCoder Beginner Contest 267

A - Saturday

Problem Statement

题意:问你给定的天到礼拜六还要几天。

思路:直接算。

#include<bits/stdc++.h>
using namespace std;

int main()
{
	string s;
	cin>>s;
	if(s=="Monday")cout<<6-1<<endl;
	else if(s=="Tuesday")cout<<6-2<<endl;
	else if(s=="Wednesday")cout<<6-3<<endl;
	else if(s=="Thursday")cout<<6-4<<endl;
	else cout<<6-5<<endl;
	return 0;
}

B - Split?

Problem Statement

emmm..藕是bd,看题意看了半天hh

题意:我们让相邻两个虚线构成一个柱子,柱子上订了别针,编号\(1\)到\(10\),告诉你每个钉子的是否被打掉的情况,问你是不是满足以下条件:

  1. 一号钉子被打掉
  2. 存在两个相邻的有钉子的柱子之间的钉子全被打掉。

Solution

思路:按题意模拟

#include<bits/stdc++.h>
using namespace std;
const int N = 10;
string s;
set<char>v[N];
int main()
{
	cin>>s;
	s = "?"+s;
	for(int i = 1;i<=10;i++)
	{
		if(i==7)v[1].insert(s[i]);
		if(i==4)v[2].insert(s[i]);
		if(i==8||i==2)v[3].insert(s[i]);
		if(i==5||i==1)v[4].insert(s[i]);
		if(i==9||i==3)v[5].insert(s[i]);
		if(i==6)v[6].insert(s[i]);
		else if(i==10)v[7].insert(s[i]);
	}
	if(s[1]=='1')
	{
		cout<<"No\n";
		return 0;
	}

	// for(int i = 1;i<=7;i++)
	// {
	// 	for(auto x:v[i])
	// 		cout<<x<<" ";
	// 	cout<<endl;
	// }
	bool ok = false;
	for(int i = 1;i<=7;i++)
	{
		for(int j = i+2;j<=7;j++)
		{
			ok = false;
			//cout<<"i = "<<i<<" j ="<<j<<endl;
			//cout<<v[i].count('1')<<" "<<v[j].count('1')<<endl;
			if(v[i].count('1')&&v[j].count('1'))
			{
				ok = true;
				for(int k = i+1;k<=j-1;k++)
				{
					if(v[k].count('1'))
					{
						//cout<<"k = "<<k<<endl;
						ok = false;
					}

				}
				if(ok)
				{
					cout<<"Yes\n";
					return 0;
				}
			}
			
		}
		
	}
	cout<<"No\n";
	return 0;
}

C - Index × A(Continuous ver.)

Problem Statement

题意:给你一个长度为n的序列\(A\),对于一段连续\(A\)的找到最大长度为\(M\)的\(\sum_{i = 1}^{M}i\times Bi\)的值

Solution

思路:双指针+前缀和思想。

\(ps\)数组记录连续的\(M\)个的数的和。每次移动,对于新的长度为\(M\)的连续段,我们发现第一个数字会离开,我们要减去它,并且恰好是一倍的它,我们发现剩下的\(M-1\)个数是我们要的,但是倍数不对,我们应该从\(1\)开始乘,但现在变成了从\(2\)开始了,也是多了一倍,那么我们只需要对当前的\(ps\)减去\(ps[i-1]\)再加上\(M*(a[i+M-1])\)。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 2e5+10;
ll n,m,ps[N],a[N];
signed main()
{
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(int i = 1;i<=n;i++)
		cin>>a[i];
	for(int i = 1;i<=m;i++)
		ps[1] += a[i];
	for(int j = 2,i = 1;j<=n-m+1;j++,i++)
		ps[j] = ps[j-1]+a[i+m]-a[i];
	ll sum = 0;
	for(int i = 1;i<=m;i++)
		sum+=a[i]*i;
	ll ans = sum;
	for(int i = 2;i<=n-m+1;i++)
	{
		sum -= ps[i-1];
		sum += a[i+m-1]*m;
		ans = max(ans,sum);
	}
	cout<<ans<<endl;
	return 0;
}

D - Index × A(Not Continuous ver.)

Problem Statement

题意:和上题一样,不过不要求取连续的\(A\)作为\(B\).

Solution

思路:DP。01背包,价值是\(a[i]*j\)

\(dp[i][j]\)表示前\(i\)个选了\(j\)个的最大价值。

#include<bits/stdc++.h>
using namespace std;
using ll  = long long;
const int N = 2100;
const ll inf = 1e18;
ll a[N],dp[N][N];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i = 0;i<n;i++)cin>>a[i];
    for(int i = 0;i<n+10;i++)
        for(int j = 0;j<m+10;j++)
            dp[i][j] = -inf;
    dp[0][0] = 0;
    for(int i = 0;i<n;i++)
    {
        for(int j = 0;j<=m;j++)
        {
            dp[i+1][j] = max(dp[i][j],dp[i][j-1]+a[i]*j);
        }
    }
    cout<<dp[n][m]<<endl;
}

E - Erasing Vertices 2

Problem Statement

题意:给你一个\(N\)个点\(M\)条边的简单无向图。每个点\(i\)有一个正整数\(Ai\)写在上面。

你将重复以下操作\(N\)次:

选择一个还没被选过的点\(x\),删除\(x\)和与\(x\)直接相连的边,代价是与\(x\)直接相连的点的权值和。问:把整张图删完,最大操作代价的最小值是多少?

Solution

思路:求最大值最小,又因为答案满足单调性,所以考虑二分答案。

\(check\)部分写法:

设最大代价是\(maxx\)

把权值和\(<=maxx\)的加入队列中,然后开始\(bfs\),遇到没被删的点,去除删掉的边,得到现在删掉所需代价,若\(<=maxx\)加入队列,直到队列为空。

因为我们要判断是不是把整个图删完了,最后判一下是不是全删了就行

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
ll n,m;
vector<ll>edge[N];
ll w[N],a[N],val[N];
bool vis[N];
queue<ll>q;
bool judge(ll maxx)
{
	ll cnt = 0;
	for(int i = 1;i<=n;i++)w[i] = val[i],vis[i] = false;
	for(int i = 1;i<=n;i++)
	{
		if(w[i]<=maxx)
			q.push(i),++cnt,vis[i] = true;
	}

	while(!q.empty())
	{
		ll x = q.front();
		q.pop();
		for(auto y:edge[x])
		{
			if(!vis[y])
			{
				w[y]-=a[x];
				if(w[y]<=maxx)
					q.push(y),++cnt,vis[y] = true;
			}
		}
	}
	return cnt == n;
}

int main()
{
	cin>>n>>m;
	for(int i = 1;i<=n;i++)
		cin>>a[i];
	for(int i = 1;i<=m;i++)
	{
		int x,y;
		cin>>x>>y;
		edge[x].push_back(y);
		edge[y].push_back(x);
		val[x] += a[y],val[y]+=a[x];
	}
	ll l = 0,r = 1e18;
	while(l<=r)
	{
		ll mid = (l+r)>>1;
		if(judge(mid))r = mid-1;
		else l = mid+1;
	}
	cout<<r+1<<endl;
	return 0;
}

标签:AtCoder,题意,int,ll,ABCDE,long,267,Statement,using
From: https://www.cnblogs.com/nannandbk/p/17504426.html

相关文章

  • AtCoder Beginner Contest 252 Ex K-th beautiful Necklace
    洛谷传送门AtCoder传送门不知道为什么可以想到设\(n_c\)为颜色\(c\)的出现次数,那么\(\prodn_c\)也即选的方案数\(\approx1.25\times10^{11}\)。发现\(B=\sqrt{\prodn_c}\)不大,考虑meet-in-the-middle,把所有颜色分成两部分,每一部分的\(\prodn_c\)都接近\(......
  • AtCoder Beginner Contest 212(E,F)
    AtCoderBeginnerContest212(E,F)E(dp)E题目大意为有\(n\)个点,我们需要找到\(k+1\)个点,用数组\(A\)表示,其中,\(A_i\)和\(A_{i+1}\)也不能一模一样,而且,规定\(A_0\)是\(1\),并且\(A_k\)也是\(1\),而且,还要满足下面的\(m\)种条边是不可以代表为\(A_i\)和\(A_{i+1}\),问我们可以......
  • AtCoder Beginner Contest(abc) 299
    A-TreasureChest题目大意给定一个由'|''*'和'.'组成的字符串,并且保证一定有1个'*'和2个'|',检查'*'是否在两个'|'之间;解题思路签到题不多嗦了;但是这里可以注意一下string的find函数;find(charc,intpos)意为从第pos个字符开始找字符c,返回值......
  • AtCoder Regular Contest 154 C Roller
    洛谷传送门AtCoder传送门被这题干爆了考虑把环压缩成块。这样一次操作就是,选择两个相邻的块,把左边块长度减\(1\),右边块长度加\(1\)。特判\(a,b\)所有块长都是\(1\)的情况,这种情况不能操作。排除掉上面的情况,我们断言:有解的充要条件是,存在某一种\(a\)的顺序,使得\(b......
  • 【题解】AtCoder-ABC306G Return to 1
    这也太强了!容易想到的是用若干环拼出这个\(10^{10^{100}}\),也就是这些环的\(\gcd\mid10\)。之后就不会了。先正图反图两次DFS,只留下\(1\)所在强连通分量里的边,对正图跑DFS生成树,定义其深度从\(0\)开始,然后有一个结论是:对于任何正整数\(a\),图中存在一个包含\(1\)......
  • AtCoder Beginner Contest 229(F,G)
    AtCoderBeginnerContest229(F,G)F(二部图,dp)F这个题大致是给你\(n+1\)个点,为\(0\)到\(n\),然后\(n\)条边是点\(0\)到\(1...n\)这些点的\(n\)条边,后面还有\(n\)条边,连接点\(i\)和\(i+1\)(其中\(i\)为\(1\)到\(n\),其中\(n\)是和\(1\)连接的)前\(n\)条边的价值是\(a_i\),后......
  • AtCoder Beginner Contest(abc) 306
    A-Echo题目大意把一个字符串的每个字符输出两遍解题思路签到题不多嗦了;神秘代码#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;typedefpair<int,int>PII;constintN=1e6+10;intn,m;signedmain(){cin>>n;string......
  • AtCoder Regular Contest 162 F Montage
    洛谷传送门AtCoder传送门题目限制可以被改写成,如果\(A_{a,b}=A_{c,d}=1\),那么\(A_{a,d}=A_{c,b}=1\)。考虑删去空白的行和列,那么对于每个\(A_{a,b}=A_{c,d}=1\),矩形\((a,b),(c,d)\)中一定都是\(1\)。发现每一行只可能存在一个极长\(1\)区间。并......
  • AtCoder Regular Contest 162 E Strange Constraints
    洛谷传送门AtCoder传送门完全没有思路。但是其实不难的。设\(d_i\)为\(i\)在\(B\)中的出现次数,题目要求:\(\foralli\in[1,n],d_i\leA_i\);对于位置\(i\),\(d_j\leA_i\)的数\(j\)可以被放到\(B_i\)。考虑按照\(d_i\)从大到小dp。设\(f_{i,j,k}\)......
  • AtCoder Beginner Contest(abc) 304
    A-FirstPlayer题目大意顺时针给定一个序列,序列的元素由一个字符串和一个数字组成;我们需要从有最小数字的元素开始,顺时针遍历整个序列,并输出字符串;解题思路签到题不多嗦了;神秘代码#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;ty......