AtCoder Beginner Contest 167 题解

题目链接
A.模拟

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
char a[N],b[N];
int main() {
  ios::sync_with_stdio(false);
  cin>>a+1>>b+1;
  int l=strlen(a+1),r=strlen(b+1);
  if(l<=r){
  	for(int i=1;i<=l;i++){
  		if(a[i]!=b[i])return cout<<"No\n",0;
  	}
  	cout<<"Yes\n";
  }else cout<<"No\n";
 	return 0;
}

B.讨论一下就行

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
LL a,b,c,k;
int main() {
  ios::sync_with_stdio(false);
  cin>>a>>b>>c>>k;
  LL d=0;
  if(k>=a)k-=a,d+=a;
  else return cout<<k,0;
  if(k>=b)k-=b;
  else return cout<<d,0;

  d-=min(k,c);
  cout<<d;
 	return 0;
}

C.枚举所有状态进行判断

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
int n,m,x;
int s[13][13];
int c[N],a[N];
const LL inf=1e18;
int main() {
  ios::sync_with_stdio(false);
  cin>>n>>m>>x;
  LL an=inf;
  for(int i=1;i<=n;i++){
  	cin>>c[i];
  	for(int j=1;j<=m;j++)cin>>s[i][j];
  }
	for(int i=0;i<(1<<n);i++){
		vector<int>v;
		for(int j=0;j<n;j++){
			if((1<<j)&i){
				v.pb(j);
			}
		}
		for(int j=1;j<=m;j++)a[j]=0;
		LL ans=0;
		for(auto k:v){
			ans+=c[k+1];
			for(int j=1;j<=m;j++){
				a[j]+=s[k+1][j];
			}
		}
		int sta=1;
		for(int j=1;j<=m;j++){
			sta&=(a[j]>=x);
		}
		if(sta)an=min(an,ans);
	}
	if(an==inf)cout<<-1<<'\n';
	else cout<<an<<'\n';
 	return 0;
}

d.先把所有非环上的点找出来,再找出环上的点,进行判断即可。
ps:注意在环上走一步后,不是第一个点。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
int n,a[N],vis[N],d[N];
LL k;
vector<int>v;
int main() {
  ios::sync_with_stdio(false);
  cin>>n>>k;
  for(int i=1;i<=n;i++){
  	cin>>a[i];
  	d[a[i]]++;
  }
  queue<int>q;
  for(int i=1;i<=n;i++){
  	if(!d[i])q.push(i);
  }
  while(!q.empty()){
  	int x=q.front();
  	vis[x]=1;
  	q.pop();
  	if(--d[a[x]]==0)q.push(a[x]);
  }
  int st=1;
  while(vis[st]){
  	st=a[st];
  	k--;
  	if(!k)return cout<<st,0;
  }
  k++;
  while(!vis[st]){
  	vis[st]=1;
  	v.pb(st);
  	st=a[st];
  }
  int s=v.size();
  k%=s;
  if(k==0)k=s;
  cout<<v[k-1]<<'\n';
 	return 0;
}

e: 至多k对相邻的颜色相同,那么把颜色相同的看成一块。
枚举x:[0-k]对相邻颜色相同,相当于从n-1块选x块使得这个块与前一个块颜色相同。
那么等价于还剩下n-x块,且相邻颜色不同,第一块的颜色有m种,剩下n-x-1每块的颜色都是m-1种颜色。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
int n,m,k;
const LL mod=998244353;
LL fac[N],inv[N];
LL pm(LL x,LL y){
  LL z=1;
  x%=mod;
  while(y){
    if(y&1)z=z*x%mod;
    x=x*x%mod;
    y>>=1;
  }
  return z;
}
void init(){
  fac[0]=1;
  for(int i=1;i<N;i++)fac[i]=fac[i-1]*i%mod;
  inv[N-1]=pm(fac[N-1],mod-2);
  for(int i=N-2;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;
}
LL get(int x,int y){
  return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n>>m>>k;
  init();
  LL ans=0;
  for(int i=0;i<=k;i++){
    ans=ans+m*get(n-1,i)%mod*pm(m-1,n-1-i)%mod;
    ans%=mod;
  }
  cout<<ans<<'\n';
 	return 0;
}

f.先把每个串的匹配括号去掉,那么剩下的串必然是a个)和b个(组成。a,b是非负整数。
然后分四种情况进行贪心排序。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
int n;
char a[N];
int l[N],r[N],cnt,vis[N],f[N];
char q[N];
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  for(int i=1;i<=n;i++){
    f[i]=i;
    cin>>a+1;cnt=0;
    int n=strlen(a+1);
    for(int j=1;j<=n;j++){
      if(a[j]=='('){
        q[++cnt]='(';
      }else{
        if(q[cnt]=='(')--cnt;
        else q[++cnt]=')';
      }
    }
    for(int j=1;j<=cnt;j++){
      if(q[j]=='(')l[i]++;
      else r[i]++;
    }
  }
  int L=0,R=0;
  sort(f+1,f+1+n,[](int x,int y){
    if(l[x]>=r[x] && l[y]<r[y])return 1;
    if(l[x]<r[x] && l[y]>=r[y])return 0;
    if(l[x]>=r[x] && l[y]>=r[y])return (int)(r[x]<r[y]);
    if(l[x]<=r[x]&&l[y]<=r[y])return (int)(l[x]>l[y]);
  });
  for(int i=1;i<=n;i++){
    if(L<r[f[i]])return cout<<"No\n",0;
    L-=r[f[i]];
    L+=l[f[i]];
  }
  if(!L)cout<<"Yes\n";
  else cout<<"No\n";
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40655981/article/details/106051379