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;
}