Codeforces Round 1021 (Div. 2)

A. Vadim's Collection

#include <bits/stdc++.h>
#define int long long
using namespace std;
int cnt[10];
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		memset(cnt,0,sizeof(cnt));
		string s;
		cin>>s;
		for(int i=0;i<s.size();i++)
		{
			cnt[s[i]-'0']++;
		}
		for(int i=9;i>=0;i--)
		{
			for(int j=i;j<=9;j++)
			{
				if(cnt[j])
				{
					cout<<j;
					cnt[j]--;
					break;
				}
			}
		}
		cout<<"\n";
	}
	return 0;
}

B. Sasha and the Apartment Purchase

#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[100005];
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		int n,k;
		cin>>n>>k;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
		}
		sort(a+1,a+n+1);
		int m=n-k;
		m=(m+1)/2;
		cout<<a[n+1-m]-a[m]+1<<"\n";
	}
	return 0;
}

C. Sports Betting

  • 终点之前也要有能否延续的判断,或许非同类逻辑不应该用else写在一起
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[100005];
map<int,int>q;
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		q.clear();
		int n;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
			q[a[i]]++;
		}
		sort(a+1,a+n+1);
		int m=unique(a+1,a+n+1)-(a+1);
		bool f=false,la=false;
		for(int i=1;i<=m;i++)
		{
			if(q[a[i]]>=4)
			{
				f=true;
				break;
			}
			if(la==true&&a[i]!=a[i-1]+1)
			{
				la=false;
			}
			if(q[a[i]]>=2)
			{
				if(la==true)
				{
					f=true;
					break;
				}
				la=true;
			}
		}
		f==true?cout<<"Yes\n":cout<<"No\n";
	}
	return 0;
}

D. Baggage Claim

  • 建图之后的结果未必是树或者基环树,有可能含多个环,这时候要判无解
#include <bits/stdc++.h>
#define int long long
using namespace std;
const signed mod=1000000007;
vector<int>a[1000005];
int x[1000005],y[1000005];
bool vis[1000005],e[1000005];
int n,m,k,cnt,tot,num;
int enc(int i,int j)
{
	return (i-1)*m+j;
}
void dfs(int u)
{
	vis[u]=true;
	tot++;
	num+=a[u].size();
	cnt+=(e[u]==true);
	for(int v:a[u])
	{
		if(vis[v]==false)
		{
			dfs(v);
		}
	}
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		cin>>n>>m>>k;
		for(int i=0;i<=k;i++)
		{
			cin>>x[i]>>y[i];
		}
		int ans=0;
		for(int i=1;i<=k;i++)
		{
			int val=-1;
			if(abs(x[i]-x[i-1])==2&&y[i]==y[i-1])
			{
				val=enc((x[i]+x[i-1])>>1,y[i]);
			}
			else if(abs(y[i]-y[i-1])==2&&x[i]==x[i-1])
			{
				val=enc(x[i],(y[i]+y[i-1])>>1);
			}
			if(val==-1)
			{
				if(abs(x[i]-x[i-1])==1&&abs(y[i]-y[i-1])==1)
				{
					int u=enc(x[i-1],y[i]),v=enc(x[i],y[i-1]);
					a[u].push_back(v);
					a[v].push_back(u);
				}
				else
				{
					goto label;
				}
			}
			else
			{
				if(e[val]==true)
				{
					goto label;
				}
				e[val]=true;
			}
		}
		ans=1;
		for(int i=1;i<=n*m;i++)
		{
			if(!vis[i])
			{
				cnt=tot=num=0;
				dfs(i);
				num/=2;
				if(cnt==0)
				{
					if(tot==num)
					{
						ans=ans*2%mod;
					}
					else if(tot==num+1)
					{
						ans=ans*tot%mod;
					}
					else
					{
						ans=0;
						break;
					}
				}
				else if(cnt==1)
				{
					if(tot==num)
					{
						ans=0;
						break;
					}
				}
				else
				{
					ans=0;
					break;
				}
			}
		}
		label:
		cout<<ans<<"\n";
		for(int i=1;i<=n*m;i++)
		{
			vis[i]=e[i]=false;
			a[i].clear();
		}
	}
	return 0;
}

E. Bermuda Triangle

  • 折线其实挺难求的,本题可以通过对称折叠的方法化折线为直线,这样问题就大大简化了
  • 如果参数含负数,那么exgcd得到的解可能是对应负gcd,也可能是对应正gcd,需要在exgcd的过程中顺便求出gcd
  • 将exgcd得到的解双向调整到想要的区间
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
pii exgcd(int a,int b,int &g)
{
	if(b==0)
	{
		g=a;
		return {1,0};
	}
	else
	{
		auto [x,y]=exgcd(b,a%b,g);
		return {y,x-a/b*y};
	}
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		int n,x,y,vx,vy;
		cin>>n>>x>>y>>vx>>vy;
		int g=__gcd(vx,vy);
		vx/=g;
		vy/=g;
		auto [p,q]=exgcd(vy*n,-vx*n,g);
		int w=vx*(n-y)-vy*(n-x);
		if(w%g)
		{
			cout<<-1<<"\n";
		}
		else
		{
			p*=(w/g);
			q*=(w/g);
			while(p<0||q<0)
			{
				int c=max({-p/vx,-q/vy,1ll});
				p+=c*vx;
				q+=c*vy;
			}
			while(p-vx>=0&&q-vy>=0)
			{
				int c=min(p/vx,q/vy);
				p-=c*vx;
				q-=c*vy;
			}
			cout<<p+q+abs(p-q)/2+(p+q+2)/2<<"\n";
		}
	}
	return 0;
}
posted @ 2025-04-27 10:59  D06  阅读(65)  评论(0)    收藏  举报
//雪花飘落效果