AtCoder Beginner Contest 167
半夜写的的题解(www
A
也可以 pop_back(b)
来判断
#include<bits/stdc++.h>
using namespace std;
int main(){
string a, b; cin>>a>>b;
for(char i='a'; i<='z'; i++){
if(a+i==b){
puts("Yes");
return 0;
}
}
puts("No");
return 0;
}
B
似乎和标程一致hh
#include<bits/stdc++.h>
using namespace std;
int main(){
int a, b, c, k; cin>>a>>b>>c>>k;
int res=0;
if(k<=a) res=k;
else if(k<=a+b) res=a;
else res=a-(k-a-b);
cout<<res<<endl;
return 0;
}
C
枚举状态
#include<bits/stdc++.h>
using namespace std;
const int M=15, N=M;
struct node{
int c;
int w[M];
}e[N];
int cur[M];
int main(){
int n, m, x; cin>>n>>m>>x;
for(int i=1; i<=n; i++){
cin>>e[i].c;
for(int j=1; j<=m; j++) cin>>e[i].w[j];
}
bool ok=false; int res=1e9;
for(int i=0; i<(1<<n); i++){
memset(cur, 0, sizeof cur);
bool fl=true;
int cost=0;
for(int j=0; j<n; j++) if(i>>j&1){
int t=j+1;
cost+=e[t].c;
for(int k=1; k<=m; k++) cur[k]+=e[t].w[k];
}
for(int k=1; k<=m; k++) if(cur[k]<x) fl=false;
if(fl){
ok=true;
res=min(res, cost);
}
}
if(!ok) puts("-1");
else cout<<res<<endl;
return 0;
}
D
肯定会出现循环,那么我们就看看环的大小是多少,从哪个点开始是循环的开端。
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
#define int long long
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=2e5+5;
int n, k;
int w[N], res[N];
bool vis[N];
int tot=1;
signed main(){
cin>>n>>k;
rep(i,1,n) read(w[i]);
res[0]=1, vis[1]=true;
int cur=1;
while(!vis[w[cur]]){
res[tot++]=w[cur];
cur=w[cur];
vis[cur]=true;
}
set0(vis);
int pt=w[cur], sz=1; // size of the loop
vis[pt]=true;
while(!vis[w[pt]]){
sz++;
pt=w[pt];
}
int d=tot-sz; // 偏移量
debug(d);
if(k<=d) cout<<res[k]<<endl;
else cout<<res[(k-d)%sz+d]<<endl;
return 0;
}
E
读错题了(大悲
这题的意思是给 \(n\) 个格子染色,使得同色连块数(共 \(n-1\) 块)不超过 \(k\) ,求方案数。
那我们就枚举同色连块数 \(i\) 为 \([0, k]\) 的情况,然后统计一下即可。
公式是:
\[m\times C_{n-1}^i \times (m-1)^{n-i-1}
\]
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const ll N=2e5+5, mod=998244353;
ll fpow(ll x,ll p)
{
ll res=1;
for(;p;p>>=1,x=x*x%mod)
if(p&1)res=res*x%mod;
return res%mod;
}
ll inv(ll x){
return fpow(x,mod-2)%mod;
}
ll fac[N];
void init(){
fac[0]=1;
for(int i=1; i<N; i++) fac[i]=fac[i-1]*i%mod;
}
ll C(ll a, ll b){
return fac[a]*inv(fac[b])%mod*inv(fac[a-b])%mod;
}
int main(){
init();
ll n, m, k; cin>>n>>m>>k;
ll res=0;
rep(i,0,k) res=(res+m*C(n-1, i)%mod*fpow(m-1, n-i-1)%mod)%mod;
cout<<res<<endl;
return 0;
}
F
又是一道贪心。
先对括号串进行处理:匹配的就当场消掉,记录下消除后的左半括号和右半括号的个数。
将处理后的括号串分成四组:只有左半括号的,左半括号多于右半括号的,右半括号多于左半括号的,只有右半的括号的。
直观的想法是先尽量减少左半括号的消耗量(即被右半括号匹配掉的数量),让它“积累”起来,这样做是最优的。
所以我们按上面的四组顺序依次进行模拟。
而对于 \(2,3\) 组,我们需要对它们进行排序,排序函数见代码,可以通过严谨的推导和证明得到排序函数(挺简单的ww),如果需要证明可以在评论区告诉我一下我补上。
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
inline void read(int &x) {
int s=0;x=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=1e6+5;
struct node{
int l, r;
}e[N];
int stk[5][N], top[5];
bool cmp(int a, int b){
return e[a].r==e[b].r? e[a].l>e[b].l: e[a].r<e[b].r;
}
bool cmp2(int a, int b){
return e[a].l==e[b].l? e[a].r<e[b].r: e[a].l>e[b].l;
}
int main(){
int n; cin>>n;
rep(i,1,n){
string t; cin>>t;
int l=0, r=0;
for(auto j: t){
if(j==')'){
if(l) l--;
else r++;
}
else l++;
}
e[i]={l, r};
if(!l && !r) continue;
if(l && !r) stk[1][++top[1]]=i;
else if(!l && r) stk[4][++top[4]]=i;
else if(l>=r) stk[2][++top[2]]=i;
else if(l<r) stk[3][++top[3]]=i;
}
sort(stk[2]+1, stk[2]+1+top[2], cmp);
sort(stk[3]+1, stk[3]+1+top[3], cmp2);
int L=0, R=0;
rep(i,1,4){
rep(j,1,top[i]){
R+=e[stk[i][j]].r;
if(R>L){
puts("No");
return 0;
}
L+=e[stk[i][j]].l;
}
}
puts(L==R? "Yes": "No");
return 0;
}