usaco 2017 jan contest gold

http://www.usaco.org/index.php?page=jan17results
A:
题意:n个数,每个数左,右边比他大的数的个数a,b。如果a,b中大数大于小数的2倍,就说这个数“不平衡”。问有多少个数不平衡。
思路:正反各一遍,用树状数组算出之前加入的数中比他大的个数。最后统计一遍。
B:
题意:n个字母(h,p,s中的一个)可以分成最多k+1个区间,每个区间的值为这个区间中字母出现最多的个数。问所有区间和最大为多少。
思路:dp,dp[i][j][k]表示考虑到第i个字母,已经分了j+1个区间,最后的区间选的作为区间答案的字母为k。
C:
题意:n*n的格子,一些格子可以达到,一些不可以。要从坐下角走到右上角,每次有3个指令,向前,左转,右转。如果一个指令无法完成,那么他跳过这个指令。如果到达终点,就不再做之后所有指令。现在一个人在左下角,但不知道他面朝的方向,问不论他面朝哪都能让他走到终点的最少指令条数。
思路:一直没有想出来,后来看题解,发现是设状态为开始面朝走到的位置,开始面朝左走到的位置,方向,是否到达过终点。跑一遍最短路就好了。

A:

#include<cstdio>
#include<string>
#include<cstring>
#include<utility>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<vector>
#include<iostream>
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define inf 0x7fffffff
#define minn(x,y) x=min(x,y)
#define maxx(x,y) x=max(x,y)
using namespace std;
pii a[100010];
int b[100010],s[100010],n,l[100010],r[100010];
int add(int x)
{
	x++;
	int i;
	for(i=x;i<n;i+=(i&-i))
	{
		s[i]++;
	}
}
int ask(int x)
{
	x++;
	int i,an=0;
	for(i=x;i>0;i-=(i&-i))
	{
		an+=s[i];
	}
	return an;
}
int main()
{
	int i,j,k,m,x,y,z;
	freopen("bphoto.in","r",stdin);
	freopen("bphoto.out","w",stdout);
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&x);
		a[i]=mp(-x,i);
	}
	sort(a,a+n);
	for(i=0;i<n;i++)
	{
		b[a[i].se]=i;
	}
	for(i=0;i<n;i++)
	{
		l[i]=ask(b[i]);
		add(b[i]);
	}
	memset(s,0,sizeof(s));
	for(i=n-1;i>=0;i--)
	{
		r[i]=ask(b[i]);
		add(b[i]);
	}
	x=0;
	for(i=0;i<n;i++)
	{
		if(r[i]>l[i]*2||l[i]>r[i]*2)
		{
			x++;
		}
	}
	printf("%d",x);
	return 0;
}

B:

#include<cstdio>
#include<string>
#include<cstring>
#include<utility>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<vector>
#include<iostream>
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define inf 0x7fffffff
#define minn(x,y) x=min(x,y)
#define maxx(x,y) x=max(x,y)
using namespace std;
int a[100010],dp[100010][23][4];
string s="HPS";
int main()
{
	int i,j,k,n,m,x,y,z;
	freopen("hps.in","r",stdin);
	freopen("hps.out","w",stdout);
	scanf("%d%d",&n,&k);
	string ch;
	for(i=0;i<n;i++)
	{
		cin>>ch;
		a[i]=s.find(ch[0]);
	}
	for(i=0;i<=k;i++)
	{
		dp[0][i][a[0]]=1;
	}
	for(i=1;i<n;i++)
	{
		dp[i][0][0]=dp[i-1][0][0]+(a[i]==0);
		dp[i][0][1]=dp[i-1][0][1]+(a[i]==1);
		dp[i][0][2]=dp[i-1][0][2]+(a[i]==2);
		for(j=1;j<=k;j++)
		{
			for(int l=0;l<3;l++)
			{
				dp[i][j][l]=max(dp[i][j-1][l],dp[i-1][j][l]+(a[i]==l));
				dp[i][j][l]=max(dp[i][j][l],dp[i-1][j-1][a[i]]+1);
			}
		}
	}
	printf("%d",max(dp[n-1][k][2],max(dp[n-1][k][0],dp[n-1][k][1])));
}

C:

#include<cstdio>
#include<string>
#include<cstring>
#include<utility>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<vector>
#include<iostream>
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define inf 0x7fffffff
#define minn(x,y) x=min(x,y)
#define maxx(x,y) x=max(x,y)
using namespace std;
int dx1[4]={-1,0,1,0},dx2[4]={0,1,0,-1};
int dy1[4]={0,1,0,-1},dy2[4]={1,0,-1,0};
int d[25][25][25][25][4][2][2],n;
bool vis[25][25][25][25][4][2][2];
int a1[25][25];
struct node
{
	int ax,ay,bx,by,dir;
	bool a,b;
	node(int ax1,int ay1,int bx1,int by1,int dir1)
	{ax=ax1;ay=ay1;bx=bx1;by=by1;dir=dir1;a=0;b=0;}
	node left()
	{
		node ans=*this;
		ans.dir=(ans.dir+3)%4;
		return ans;
	}
	node right()
	{
		node ans=*this;
		ans.dir=(ans.dir+1)%4;
		return ans;
	}
	bool iffr()
	{
		if((ax+dx1[dir]>=0&&ax+dx1[dir]<n&&ay+dy1[dir]>=0&&ay+dy1[dir]<n&&
		a1[ax+dx1[dir]][ay+dy1[dir]])||(bx+dx2[dir]>=0&&bx+dx2[dir]<n&&by+dy2[dir]>=0&&
		by+dy2[dir]<n&&a1[bx+dx2[dir]][by+dy2[dir]]))
		{
			return 1;
		}
		return 0;
	}
	node front()
	{
		node ans=*this;
		if(ax+dx1[dir]>=0&&ax+dx1[dir]<n&&ay+dy1[dir]>=0&&
		ay+dy1[dir]<n&&a1[ax+dx1[dir]][ay+dy1[dir]]) 
		{
			ans.ax+=dx1[dir];
			ans.ay+=dy1[dir];
		}
		if(bx+dx2[dir]>=0&&bx+dx2[dir]<n&&by+dy2[dir]>=0&&
		by+dy2[dir]<n&&a1[bx+dx2[dir]][by+dy2[dir]])
		{
			ans.bx+=dx2[dir];
			ans.by+=dy2[dir];
		}
		if(ans.ax==0&&ans.ay==n-1)
		{
			ans.a=1;
		}
		if(ans.bx==0&&ans.by==n-1)
		{
			ans.b=1;
		}
		return ans;
	}
}now(0,0,0,0,0),nxt(0,0,0,0,0);
string s;
int main()
{
	int i,j,k,m,x,y,z;
	freopen("cownav.in","r",stdin);
	freopen("cownav.out","w",stdout);
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		cin>>s;
		for(j=0;j<n;j++)
		{
			a1[i][j]=s[j]=='E';
		}
	}
	queue<node> q;
	memset(d,0x3f,sizeof(d));
	q.push(node(n-1,0,n-1,0,0));
	vis[n-1][0][n-1][0][0][0][0]=1;
	d[n-1][0][n-1][0][0][0][0]=0;
	while(!q.empty())
	{
		now=q.front();
		q.pop();
		if(now.a&now.b)
		{
			break;
		}
		nxt=now.left();
		if(d[now.ax][now.ay][now.bx][now.by][now.dir][now.a][now.b]+1<
		d[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b])
		{
			d[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b]=
			d[now.ax][now.ay][now.bx][now.by][now.dir][now.a][now.b]+1;
			if(!vis[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b])
			{
				vis[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b]=1;
				q.push(nxt);
			}
		}
		nxt=now.right();
		if(d[now.ax][now.ay][now.bx][now.by][now.dir][now.a][now.b]+1<
		d[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b])
		{
			d[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b]=
			d[now.ax][now.ay][now.bx][now.by][now.dir][now.a][now.b]+1;
			if(!vis[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b])
			{
				vis[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b]=1;
				q.push(nxt);
			}
		}
		if(now.iffr())
		{
			nxt=now.front();
			if(d[now.ax][now.ay][now.bx][now.by][now.dir][now.a][now.b]+1<
			d[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b])
			{
				d[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b]=
				d[now.ax][now.ay][now.bx][now.by][now.dir][now.a][now.b]+1;
				if(!vis[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b])
				{
					vis[nxt.ax][nxt.ay][nxt.bx][nxt.by][nxt.dir][nxt.a][nxt.b]=1;
					q.push(nxt);
				}
			}
		}
		vis[now.ax][now.ay][now.bx][now.by][now.dir][now.a][now.b]=0;
	}
	int mi=0x7fffffff;
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			for(k=0;k<n;k++)
			{
				for(int l=0;l<n;l++)
				{
					for(m=0;m<4;m++)
					{
						mi=min(mi,d[i][j][k][l][m][1][1]);
					}
				}
			}
		}
	}
	printf("%d",mi);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值