【BestCoder Round #75 1005】King's Pilots

BestCoder Round #67

Zarxdy34 posted @ 2016年1月07日 19:32 in BestCoder with tags bc , 623 阅读
 

【N bulbs】

 

#include <cstdio>
#include <cstring>
using namespace std;

int main()
{
	int T,n;
	scanf("%d",&T);
	while (T--)
	{
		scanf("%d",&n);
		int cnt=0;
		for (int i=1,x;i<=n;i++) scanf("%d",&x),cnt+=x==0;
		if (cnt&1) printf("NO\n");else printf("YES\n");
	}
	return 0;
}

 

【N*M bulbs】

  显然,如果走两个0的格子,至少需要走两格,也就是走偶数步。走1的格子等同于走奇数步。判断走的步数的奇偶性即可。

 

#include <cstdio>
#include <cstring>
using namespace std;

int main()
{
	int T,n,m;
	scanf("%d",&T);
	while (T--)
	{
		scanf("%d%d",&n,&m);
		int cnt=0,x;
		for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			scanf("%d",&x),cnt+=x;
		if ((n+m-2-cnt+1000000)&1) printf("YES\n");else printf("NO\n");
	}
	return 0;
}

 

【Black Jack】

  一个比较经典的概率DP。

  设f2[i][j]为闲家点数为i后停止叫牌,庄家此时点数为j时庄家的胜率(平局当作庄家赢),则f2[i][j]等于取一张点数为k的牌的概率乘上f2[i][j+k]。

  设f1[i][j]为庄家初始点数为j,闲家当前点数为i时闲家的胜率,f1[i][j]为闲家抽一张牌的胜率与不抽牌胜率的最大值。

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

double f1[40][40],f2[40][40];

void DP()
{
	for (int i=1;i<=21;i++)
	for (int j=i;j<=21;j++)
		f2[i][j]=1;
	for (int i=1;i<=21;i++)
	for (int j=i-1;j>=1;j--)
	{
		for (int k=1;k<=9;k++) f2[i][j]+=f2[i][j+k]/13.0;
		f2[i][j]+=f2[i][j+10]*4.0/13.0;
	}
	for (int i=21;i>=1;i--)
	for (int j=21;j>=1;j--)
	{
		for (int k=1;k<=9;k++) f1[i][j]+=f1[i+k][j]/13.0;
		f1[i][j]+=f1[i+10][j]*4.0/13.0;
		f1[i][j]=max(f1[i][j],1.0-f2[i][j]);
	}
}

int Change(char ch) {if (ch>='2' && ch<='9') return ch-'0';else if (ch=='A') return 1;else return 10;}

int main()
{
	DP();
	int T;
	scanf("%d",&T);
	while (T--)
	{
		char cor[5];
		scanf("%s",cor);
		if (f1[Change(cor[0])+Change(cor[1])][Change(cor[2])+Change(cor[3])]>0.5) puts("YES");else puts("NO");
	}
}

 

【the soldier of love】

  记录下所有的点以及它们对应的组号,以及每个点同组的前一个点的位置,然后把它们在数轴上按顺序排成一排。

  用一个长度为数轴长的树状数组记录线段的左端点(即如果有一条线段左端点为x,则树状数组上这个点的值+1),维护前缀和。

  从左往右遍历点,对每个点p对应的组的答案加上树状数组里区间[p.prev_position+1,p.position]的和。在这过程中将右端点在当前点左边的线段标记从树状数组中删除。

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=300010,maxl=1000010;

struct Segment {int l,r;}S[maxn];
struct Point {int x,id,prev;}P[maxn];
bool cmps(const Segment &a,const Segment &b) {return a.r<b.r;}
bool cmpp(const Point &a,const Point &b) {return a.x<b.x;}

int f[maxl];
int ans[maxn];
int n,m,T;

inline int lowbit(int x) {return x&-x;}
void Change(int x,int o) {while (x<maxl) f[x]+=o,x+=lowbit(x);}
int Query(int x) {int res=0;while (x) res+=f[x],x-=lowbit(x);return res;}

int main()
{
	while (scanf("%d%d",&n,&T)==2)
	{
		memset(f,0,sizeof(f));
		memset(ans,0,sizeof(ans));
		m=0;
		for (int i=1;i<=n;i++) scanf("%d%d",&S[i].l,&S[i].r);
		sort(S+1,S+1+n,cmps);
		for (int i=1;i<=T;i++)
		{
			int ki,lastpos=0;
			scanf("%d",&ki);
			while (ki--) scanf("%d",&P[++m].x),P[m].id=i,P[m].prev=lastpos,lastpos=P[m].x;
		}
		sort(P+1,P+1+m,cmpp);
		for (int i=1;i<=n;i++) Change(S[i].l,1);
		for (int i=1,p=0;i<=m;i++)
		{
			int id=P[i].id,x=P[i].x;
			while (p<n && x>S[p+1].r) Change(S[++p].l,-1);
			ans[id]+=Query(x)-Query(P[i].prev);
		}
		for (int i=1;i<=T;i++) printf("%d\n",ans[i]);
	}
	return 0;
}

 

【merge】

  你TM倒是告诉我题目到底是什么意思......

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter