NEC Programming Contest 2021 (AtCoder Beginner Contest 229)

终于开始补提了
重点 : C, E的倒着算, F的染色,G的相邻的转换;
B - Hard Calculation

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 4e5+10, mod = 1e9+7;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}

int main() 
{
	LL a, b;
	scanf("%lld%lld", &a, &b);
	while(a||b)
	{
		if(a%10 + b%10 >= 10)return puts("Hard"), 0;
		a /= 10; b /= 10;
	}
	puts("Easy");
	return 0;
}

C - Cheese
思路 : 倒着算,直接减,和上海热身赛B都好神奇。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 3e5+10, mod = 998244353;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}

int n, w;
PII a[N];
int main()
{
	scanf("%d%d", &n, &w);
	for(int i = 1;i <= n;i ++)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		a[i] = {-x, y};
	}
	sort(a+1, a+n+1);
	LL ans = 0;
	for(int i = 1;i <= n;i ++)
	{
		int mi = min(a[i].second, w);
		ans += (LL)mi*a[i].first;
		w -= mi;
	}
	cout<<-ans<<endl;
	return 0;
}

D - Longest X
思路 : 双指针或二分,练一下双指针,哎。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 2e5+10, mod = 1e9+7;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}

char c[N];
int main() 
{
	int k;
	scanf("%s%d", c, &k);
	int num = 0, l = 0, r = 0, ans = 0;
	while(c[r])
	{
		if(c[r] == 'X') r++;
		else if(num == k) num -= c[l++]=='.';
		else if(num < k) num ++, r++;
		ans = max(ans, r-l);
	}
	cout<<ans<<endl;
	return 0;
}

E - Graph Destruction
思路 :从后往前算,倒着并查集合并。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 2e5+10, mod = 1e9+7;

vector<int>G[N];
int fa[N], num = 0;
int find(int u){return fa[u] == u ? fa[u]:fa[u] = find(fa[u]);}

void dfs(int u)
{
	if(!u)return ;
	int t = num;
	num++;
	int y = find(u);
	for(auto x : G[u])
	{
		int a = find(x);
		if(a != y) num--, fa[a] = y;
	}
	dfs(u-1);
	cout<<t<<endl;
	return ;
}
int main() 
{
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 1;i <= n;i ++) fa[i] = i;
	while(m --)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		if(a > b) swap(a, b);
		G[a].push_back(b);
	}
	dfs(n);
	return 0;
}

F - Make Bipartite
思路 : dp,给每个点染色之后就可以清晰的得到要删哪条边了,但是这是个封闭图形,题解就确定了起点的颜色,然后算到第n个点,这时候先不考虑n到1的边 。 然后再枚举n和1的四种颜色组合,枚举的时候要注意n到0的边已经删过了,因为这个wa了两次。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 3e5+10, mod = 998244353;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}

LL dp[N][2][2];
int a[N], b[N];

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1;i <= n;i ++)scanf("%d", a+i);
	for(int i = 1;i <= n;i ++)scanf("%d", b+i);
	
	memset(dp, 0x7f, sizeof dp);
	dp[1][0][0] = a[1];
	dp[1][1][1] = 0;
	for(int i = 2;i <= n;i ++)
	{
		dp[i][1][0] = min(dp[i-1][1][0]+b[i-1], dp[i-1][0][0]);
		dp[i][1][1] = min(dp[i-1][1][1]+b[i-1], dp[i-1][0][1]);
		dp[i][0][0] = min(dp[i-1][1][0], dp[i-1][0][0]+b[i-1])+a[i];
		dp[i][0][1] = min(dp[i-1][1][1], dp[i-1][0][1]+b[i-1])+a[i];
	}
	cout<<min(min(dp[n][0][0], dp[n][1][1]) + b[n], min(dp[n][1][0], dp[n][0][1]));
	
	return 0;
}

G - Longest Y

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 3e5+10, mod = 998244353;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}

int b[N], idx;  //  看哪个题解的,放到一起连续就是坐标减去指数相等。 
string c;
LL k, a[N]; // a数组是前缀和,方便计算一段区间放到的最小步数; 
 
bool ch(int len)  
{
	for(int r = len;r <= idx;r ++)
	{
		int l = r-len+1, lle = mid-l+1;
		LL sum = (LL)b[mid]*lle - (a[mid]-a[l-1]) + a[r]-a[mid] - (LL)b[mid]*(len-lle);
		if(sum<=k)return 1; 
	}
	return 0;
}

int main()
{

	cin>>c>>k;
	for(int i = 0;i < c.size();i ++)
		if(c[i] == 'Y')
			b[++idx] = i-idx;
			
	sort(b+1, b+idx+1);
	for(int i = 1;i <= idx;i ++)a[i] = a[i-1]+b[i];
	
	int l = 0, r = idx+1;
	while(l < r) // 二分都是找到连续区间的右边的左端点; 
	{
		if(ch(mid))l = mid+1;
		else r = mid; 
	}
	cout<<--l<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李昌荣。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值