AtCoder Beginner Contest 167 Solution

前言

难得一次ak ABC.
但是只剩10分钟,可怜.
手速和对普及算法的熟练程度都有待提高啊…

正题

A A A

考察string的基本运用.(这样写更短)

int main() {
	string s,t;
	cin>>s>>t;
	for(char c='a';c<='z';c++)
		if(s+c==t) puts("Yes"),exit(0);
	puts("No"); 
	return 0;
}

B B B

入门的贪心

int a,b,c,k,ans;

int main() {
	qr(a); qr(b); qr(c); qr(k);
	if(k<=a) ans=k;
	else {
		ans=a;
		k-=a;
		if(k>b) ans-=k-b;
	}
	pr2(ans);
	return 0;
}

C C C

暴力 d f s dfs dfs.

int n,m,t,ans,c[N],a[N][N],b[N];

void dfs(int x,int s) {
	if(s>=ans) return ;
	if(x>n) {
		for(int i=1;i<=m;i++) if(b[i]<t) return ;
		ans=s; 
		return ;
	}
	dfs(x+1,s);
	for(int i=1;i<=m;i++) b[i]+=a[x][i];
	dfs(x+1,s+c[x]);
	for(int i=1;i<=m;i++) b[i]-=a[x][i];
}

int main() {
	qr(n); qr(m); qr(t);
	for(int i=1;i<=n;i++) {
		qr(c[i]);
		for(int j=1;j<=m;j++) qr(a[i][j]),b[j]+=a[i][j];
	}
	for(int j=1;j<=m;j++) if(b[j]<t) puts("-1"),exit(0);
	ans=1e9; memset(b,0,sizeof b); dfs(1,0); pr2(ans);
	return 0;
}

D D D

我被坑了一次.
一开始打了一个认为1号点一定在环的打法->WA.

其实本题就是找一下循环节.
在进环之前特判一下即可.

int n,a[N],v[N],cnt,f[N];
ll k;

int main() {
	qr(n);qr(k);for(int i=1;i<=n;i++) qr(a[i]);
	int x=1;
	do {
		v[x]=1;
		if(cnt==k) pr2(x),exit(0);
		f[cnt++]=x;
		x=a[x];
	} while(!v[x]);
	k-=cnt; cnt=0;
	do {
		v[x]=2;
		f[cnt++]=x;
		x=a[x];
	} while(!(v[x]&2));
	pr2(f[k%cnt]);
	return 0;
}

E E E

组合数学裸题,但是不知为啥我会先去跑去做F这么恶心的题目.
a n s = ∑ i = 0 k m C n − 1 k ∗ ( m − 1 ) n − 1 − k ans=\sum_{i=0}^k mC_{n-1}^k*(m-1)^{n-1-k} ans=i=0kmCn1k(m1)n1k
理解: m 是 第 一 个 数 的 方 案 , i 表 示 相 同 的 相 邻 数 的 个 数 , 剩 下 的 n − 1 − k 个 数 的 方 案 为 m − 1 m是第一个数的方案,i表示相同的相邻数的个数,剩下的n-1-k个数的方案为m-1 m,i,n1km1

int n,m,k;
ll jc[N],inv[N],p[N],ans;

ll power(ll a,ll b=mod-2) {
	ll c=1;
	while(b) {
		if(b&1) c=c*a%mod;
		b /= 2; a=a*a%mod;
	}
	return c;
}

ll C(int x,int y) {return jc[x]*inv[y]%mod*inv[x-y]%mod;}


int main() {
	qr(n); qr(m); qr(k);
	jc[0]=1;for(int i=1;i<=n;i++) jc[i]=jc[i-1]*i%mod;
	inv[n]=power(jc[n]);for(int i=n;i;i--) inv[i-1]=inv[i]*i%mod;
	p[0]=1;for(int i=1;i<=n;i++) p[i]=p[i-1]*(m-1)%mod;
	
	for(int i=0;i<=k;i++)
		(ans += C(n-1,i)*p[n-1-i]) %= mod;
	pr2(ans*m%mod);
	return 0;
}

F F F

比赛的时候打了个假的算法还过了,AT数据是真心水。

感谢评论区的师兄指出我原来代码的错误贪心。

类似题目

本题只比上面这个题目多了个模拟栈。

#include
#include
using namespace std;
const int N=1e6+10;

struct rec {
	int x,y;
} a[N],b[N];
int la,lb;

bool cmp1(rec a,rec b) {return a.x<b.x;}
bool cmp2(rec a,rec b) {return a.y>b.y;}

int n,s0,s1,m;
char s[N];

int main() {
	scanf("%d",&n);
	for(int i=1,l,r;i<=n;i++) {
		scanf("%s",s+1); l=r=0;
		for(int j=1;s[j];j++)
			if(s[j]=='(') l++;
			else if(l) l--;
			else r++;
		//-r +l
		if(r<l) a[++la]=(rec){r,l};
		else b[++lb]=(rec){r,l};
		s0+=r; s1+=l;
	}
	if(s0^s1) return puts("No"),0;
	sort(a+1,a+la+1,cmp1);
	sort(b+1,b+lb+1,cmp2);
	for(int i=1;i<=la;i++) {
		if(m<a[i].x) return puts("No"),0;
		m-=a[i].x-a[i].y;
	}
	for(int i=1;i<=lb;i++) {
		if(m<b[i].x) return puts("No"),0;
		m-=b[i].x-b[i].y;
	}
	puts("Yes"); return 0;
}

你可能感兴趣的:(比赛)