• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
nannandbk
博客园    首页    新随笔    联系   管理    订阅  订阅
AtCoder Beginner Contest 264 ABCDE

AtCoder Beginner Contest 264

A - "atcoder".substr()

Problem Statement

题意:截取字符串 atcoder的[L,R]一段并输出。

Solution

题解:

用string.substr直接写

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


int main()
{
	string s = "?atcoder";
	int l,r;
	cin>>l>>r;
	cout<<s.substr(l,r-l+1)<<endl;
	return 0;
}

B - Nice Grid

Problem Statement

题意:给你一个图,由黑白块组成。

给你一个坐标问你是黑的还是白的

Solution

思路:直接暴力模拟

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


int main()
{
	int n,m;
	cin>>n>>m;
	if(n==15||n==1||m==15||m==1)cout<<"black\n";
	else if(n==2||n==14)cout<<"white\n";
	else if(n==3||n==13)
	{
		if(m==2||m==14)cout<<"white\n";
		else cout<<"black\n";
	}
	else if(n==4||n==12)
	{
		if(m==3||m==13)cout<<"black\n";
		else cout<<"white\n";
	}
	else if(n==5||n==11)
	{
		if(m==2||m==4||m==14||m==12)cout<<"white\n";
		else cout<<"black\n";
	}
	else if(n==6||n==10)
	{
		if(m==3||m==5||m==13||m==11)cout<<"black\n";
		else cout<<"white\n";
	}
	else if(n==7||n==9)
	{
		if(m==2||m==4||m==6||m==10||m==12||m==14)cout<<"white\n";
		else cout<<"black\n";
	}
	else
	{
		if(n%2)cout<<"black\n";
		else cout<<"white\n";
	}

	return 0;
}

C - Matrix Reducing

Problem Statement

题意:给你两个矩阵,问你能否通过对第一个矩阵删除任意行和任意列得到第二个矩阵。

Solution

思路:数据范围只有10,直接暴力,二进制枚举选第一个矩阵的哪几个即可,再check是不是和第二个矩阵长得一样。

#include<bits/stdc++.h>
using namespace std;
const int N = 15;
int a[N][N],b[N][N];

int main()
{
	int h1,w1,h2,w2;
	cin>>h1>>w1;
	for(int i = 1;i<=h1;i++)
		for(int j = 1;j<=w1;j++)
			cin>>a[i][j];
	cin>>h2>>w2;
	for(int i = 1;i<=h2;i++)
		for(int j = 1;j<=w2;j++)
			cin>>b[i][j];
	for(int i = 0;i<(1<<h1);i++)
	{
		for(int j = 0;j<(1<<w1);j++)
		{
			vector<int>x,y;
			for(int k = 0;k<h1;k++)
				if((i>>k)&1)x.push_back(k+1);

			for(int k = 0;k<w1;k++)
				if((j>>k)&1)y.push_back(k+1);

			if((int)x.size()!=h2||(int)y.size()!=w2)continue;
			bool ok = true;
			for(int k = 1;k<=h2;k++)
			{
				for(int l = 1;l<=w2;l++)
				{
					if(a[x[k-1]][y[l-1]]!=b[k][l])
					{
						ok = false;
						break;
					}
				}
				if(!ok)break;
			}
			if(ok)
			{
				cout<<"Yes\n";
				return 0;
			}
		}
	}
	cout<<"No\n";
	return 0;
}

D - "redocta".swap(i,i+1)

Problem Statement

思路:给你一个字符串,你可以交换相邻两个位置的字符,问你至少交换多少次可以得到字符串atcoder.

Solution

思路:bfs。

当前串可以通过交换任意两个字符得到新串,代价为1,那可以考虑bfs写。

用map记录这个串有没有得到过,因为如果得到过,由现在的转移到得到过的串一定不会更优。

最后输出答案。

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

int main()
{
	string s;
	cin>>s;
	unordered_map<string,int>mp;
	mp[s] = 0;
	queue<string>q;
	q.push(s);
	while(!q.empty())
	{
		string t = q.front();
		q.pop();
		if(t=="atcoder")
		{
			cout<<mp[t]<<endl;
			return 0;
		}
		for(int i = 0;i<6;i++)
		{
			string cur = t;
			swap(cur[i],cur[i+1]);
			if(!mp[cur])
			{
				mp[cur] = mp[t]+1;
				q.push(cur);
			}
		}
	}
	return 0;
}

E - Blackout 2

Problem Statement

题意:

一个国家由N个城市和M个发电厂。

一共由N+M个建筑,1,2...N个是城市,N+1,N+2...M个是发电厂。

这个国家由E条电线,告诉你这E条线的连接。

一个城市称为有电当且仅当可以到达至少一个发电厂。

现在有Q个事件,每次删去一条电线,询问删去后还有多少个城市有电。

Solution

思路:正向不好考虑,因为还要删边。我们考虑离线+反向加边。这样原本有电的不会变成没有电,就好处理很多。

那么我们要如何判断一个城市是否有电?

并查集。每次令父亲是大的那个,这样保证如果连到发电厂(>n),能被识别。还要注意记录每个并查集的大小,这样连接的时候才知道要加上几个。为什么这样是可以的呢?因为每个并查集只有一个父亲,那我们又令父亲是最大的,如果最大的都<=n,那说明没有电,如果此时连上了一个>n的,说明整个并查集的元素都可以有电。

即:

如果fx<=n&&fy>n,cnt += sz[fx],fa[fx] = fy

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5+10;
bool ok[N];
map<int,pair<int,int>>mp;
int evt[N];
vector<int>edge[N*2];
int fa[N],ans[N],sz[N];
int find(int x)
{
	if(x==fa[x])
		return x;
	return fa[x] = find(fa[x]);
}
int main()
{
	int n,m,e;
	cin>>n>>m>>e;
	for(int i = 1;i<=n+m;i++)
		fa[i] = i;
	for(int i = 1;i<=n;i++)
		sz[i] = 1;
	for(int i = 1;i<=e;i++)
	{
		int x,y;
		cin>>x>>y;
		mp[i] = {x,y};
	}
	int q;
	cin>>q;
	set<int>s;
	for(int i = 1;i<=q;i++)
	{
		cin>>evt[i];
		s.insert(evt[i]);
	}
	int cnt = 0;
	for(int i = 1;i<=e;i++)
	{
		if(s.find(i)==s.end())
		{
			auto t = mp[i];
			int x = t.first,y = t.second;
			int fx = find(x),fy = find(y);
			if(fx>fy)swap(fx,fy);
			if(fx!=fy)
			{
				if(fx<=n&&fy>n)
					cnt += sz[fx];
				fa[fx] = fy;
				sz[fy] += sz[fx]; 
			}
		}
	}


	for(int i = q;i>=1;i--)
	{
		ans[i] = cnt;
		auto t = mp[evt[i]];
		int x = t.first,y = t.second;
		int fx = find(x),fy = find(y);
		if(fx>fy)swap(fx,fy);
		if(fx!=fy)
		{
			if(fx<=n&&fy>n)
					cnt += sz[fx];
			fa[fx] = fy;
			sz[fy] += sz[fx]; 
		}
	}


	for(int i = 1;i<=q;i++)
		cout<<ans[i]<<endl;

	return 0;
}
posted on 2023-07-07 17:23  nannandbk  阅读(103)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3