ABC 377 Review

ABC 377 Review

A

模拟题,但是好像wa了一发,有点幽默

Code

#include<bits/stdc++.h>
using namespace std;
char s[5];
int main()
{
	for(register int i=1;i<=3;++i)s[i]=getchar();
	sort(s+1,s+4);
	if(s[1]=='A'&&s[2]=='B'&&s[3]=='C')cout<<"Yes";
	else cout<<"No";
	return 0;
}

B C

都是模拟题,甚至但是C题还是需要注意一下细节,去掉算重的答案就可以了。

CodeB

#include<bits/stdc++.h>
using namespace std;
char mp[10][10];
int n=8;
inline void input()
{
	for(register int i=1;i<=n;++i)
		for(register int j=1;j<=n;++j)
			cin>>mp[i][j];
}
inline bool check(int x,int y)
{
	for(register int i=1;i<=n;++i)
	{
		if(i==x)continue;
		if(mp[i][y]=='#')return 0; 
	}
	for(register int j=1;j<=n;++j)
	{
		if(j==y)continue;
		if(mp[x][j]=='#')return 0; 
	}
	return 1;
}
inline int calc()
{
	int ans=0;
	for(register int i=1;i<=n;++i)
	{
		for(register int j=1;j<=n;++j)
		{
			if(mp[i][j]=='#')continue;
			if(check(i,j))ans++;
		}
	}
	return ans;
}
int main()
{
	input();
	cout<<calc();
	return 0;
}

CodeC

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
inline bool valid(int x,int y)
{
	return 1<=x&&x<=n&&1<=y&&y<=n;
}
map<int,map<int,int>> vis;
int c1[8]={2,1,-1,-2,-2,-1,1,2},c2[8]={1,2,2,1,-1,-2,-2,-1};
inline void calc(int x,int y,int &ans)
{
	for(register int t=0;t<8;++t)
	{
		int tx=x+c1[t],ty=y+c2[t];
		if(!valid(tx,ty))continue;
		if(!vis[tx][ty])ans--,vis[tx][ty]=1;
	}
}
inline void solve()
{
	cin>>n>>m;
	int x,y;
	long long ans=n*n-m;
	for(register int i=1;i<=m;++i)
	{
		scanf("%lld%lld",&x,&y);
		if(vis[x][y])ans++;
		vis[x][y]=1;
		calc(x,y,ans);
	}
	cout<<ans;
}
signed main()
{
	solve();
	return 0;
}

D

太经典了,一卡题就坐牢,这次坐了一个小时的牢。

分析

其实还是想到了算法的。考虑如果一个左端点固定的话,那么它的右端点可以怎么取?

那么很显然地可以想到如下算法流程:

\(1-m\) 枚举左端点,每次经过了一个左端点,就把这个左端点和它对应的右端点一起删除掉。

那么假设当前枚举到了 \(x\) ,我们最多能取的右端点,肯定是当前还存在的最小右端点 \(-1\)

这样我们在这个位置上的 \(ans\) 就是 \((Min_r-1)-x+1=Min_r-x\)

细节

如果当前的区间已经被全部删没了,那么实际上还是可以产生答案,所以我们还要插入一个 \(m+1\) 的右端点。

左右端点都是可重的,因此对于每一个左端点,我们都要开一个vector来记录有哪些右端点与其对应,才可以方便删除。

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=4e5+10;
template<typename T>inline void re(T &x)
{
	x=0;
	int f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	x*=f;
}
int n,m;
multiset<int>visl,visr;
inline void solve()
{
	re(n),re(m);
	vector<int> Rl[m+1]; 
	for(register int i=1,l,r;i<=n;++i)
	{
		re(l),re(r);
		visl.insert(l);
		visr.insert(r);
		Rl[l].push_back(r);
	}
	visr.insert(m+1);
	long long ans=0;
	for(register int x=1;x<=m;++x)
	{
		while(visl.size()&&visl.count(x-1))
		{
			visl.erase(visl.lower_bound(x-1));
			visr.erase(visr.lower_bound(Rl[x-1][Rl[x-1].size()-1]));
			Rl[x-1].pop_back();
		}
		int findr=*visr.upper_bound(0);
		ans+=findr-x;
	}
	cout<<ans;
} 
signed main()
{
	solve();
	return 0;
}

总结

又强化了set的使用技巧,学到了可重点对的记录方式。

最重要的是想到了就去写,代码能力就是不断锻炼出来的。

没有思路就换个角度,或者是开另外一道题。

posted @ 2024-10-27 16:18  Hanggoash  阅读(11)  评论(0编辑  收藏  举报
动态线条
动态线条end