usaco 2015 dec contest gold

http://www.usaco.org/index.php?page=dec15results
A:
题意:2* n张牌编号1-2*n,你和对手各n张,你已经知道了对手的牌和出牌顺序(也就是知道了自己的牌)。共n轮出牌,每轮没人出一张。前n/2(n是偶数)轮点数大的人得分,后n/2轮点数小的人得分。求你的最大得分。
思路:对于前n/2轮,尽量把大牌打出。后半场尽量把小牌打出。所以可以把前后半场对手出牌分别排序,各扫一遍数出最多能得多少分。
B:
题意:一头牛最多吃T单位东西,有两种无限多的东西可以吃,质量分别为a,b。中间可以喝一次水,使吃的东西减半(下取整),问最后最多肚子里有多少东西。
思路:dp求出不喝水可以达到的值,分别除以二得到喝水后可以得到的值。枚举喝水后吃了多少,在除以二得到的值中二分查找,算出此时最多吃了多少。不论是dp的数组还是除以二得到的数组都要保留0避免下表出错和保证不喝水的情况被考虑。
C:
题意:n * m的表格,每个格有4种颜色,分别表示0不能通过,1可以通过,2可以通过并沾上气味,3有气味可以过,没有气味不能过,4跳过此格并消除气味。2类格沾上的气味一直保持知道经过4类格才会消去。问左上角走到右下角最少步数。
思路:每个格有两种状态:有气味和没有气味。于是设一个数组b[i][j][k(0/1)]表示在i行j列有无气味时的最短路程。bfs一遍,每个格至多过2次,就可以过了。

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;
int a[50010],c[100010],b[50010];
int main()
{
	int i,j,k,n,m,x,y,z,t;
	freopen("cardgame.in","r",stdin);
	freopen("cardgame.out","w",stdout);
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		c[a[i]]=1;
	}
	j=0;
	for(i=1;i<=2*n;i++)
	{
		if(c[i]==0)
		{
			b[j]=i;
			j++;
		}
	}
	sort(a,a+n/2);
	reverse(a,a+n/2);
	sort(a+n/2,a+n);
	j=n-1;
	for(i=0;i<n/2;i++)
	{
		while(i<n/2&&a[i]>b[j])
		{
			i++;
		}
		if(i<n/2)
		{
			j--;
		}
	}
	k=0;
	for(i=n/2;i<n;i++)
	{
		while(i<n&&a[i]<b[k])
		{
			i++;
		}
		if(i<n)
		{
			k++;
		}
	}
	printf("%d",k+n-1-j);
}

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 dp[5000010];
int main()
{
	int i,j,k,n,m,x,y,z,t;
	freopen("feast.in","r",stdin);
	freopen("feast.out","w",stdout);
	scanf("%d%d%d",&n,&x,&y);
	dp[0]=1;
	for(i=x;i<=n;i++)
	{
		dp[i]=dp[i]|dp[i-x];
	}
	for(i=y;i<=n;i++)
	{
		dp[i]=dp[i]|dp[i-y];
	}
	vector<int> ve;
	for(i=0;i<=n;i++)
	{
		if(dp[i])
		{
			if(ve.empty()||ve.back()!=i/2)ve.push_back(i/2);
		}
	}
	z=0;
	for(i=0;i<=n;i++)
	{
		if(dp[i])
			z=max(z,i+*(lower_bound(ve.begin(),ve.end(),n-i+1)-1));
	}
	printf("%d",z);
}

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 a[1010][1010],n,m,b[1010][1010][2];
pair<pii,int> go(pii x,int y,int dx,int dy)
{
	int z=0;
	while(x.fi+dx>=0&&x.fi+dx<n&&x.se+dy>=0&&x.se+dy<m&&a[x.fi+dx][x.se+dy]==4)
	{
		x=mp(x.fi+dx,x.se+dy);
		y=0;
		z=1;
	}
	if(x.fi+dx>=0&&x.fi+dx<n&&x.se+dy>=0&&x.se+dy<m&&a[x.fi+dx][x.se+dy]==0)
	{
		if(z)return mp(x,0);
		return mp(mp(-1,0),0);
	}
	if(x.fi+dx>=0&&x.fi+dx<n&&x.se+dy>=0&&x.se+dy<m&&a[x.fi+dx][x.se+dy]==1)return mp(mp(x.fi+dx,x.se+dy),y);
	if(x.fi+dx>=0&&x.fi+dx<n&&x.se+dy>=0&&x.se+dy<m&&a[x.fi+dx][x.se+dy]==2)return mp(mp(x.fi+dx,x.se+dy),1);
	if(x.fi+dx>=0&&x.fi+dx<n&&x.se+dy>=0&&x.se+dy<m&&a[x.fi+dx][x.se+dy]==3)
	{
		if(y==0)
		{
			if(z)return mp(x,0);
			return mp(mp(-1,0),0);
		}
		return mp(mp(x.fi+dx,x.se+dy),1);
	}
	return mp(x,y);
}
int main()
{
	int i,j,k,z,t;
	freopen("dream.in","r",stdin);
	freopen("dream.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(i=0;i<n;i++)
	{
		for(j=0;j<m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	memset(b,0x3f,sizeof(b));
	priority_queue<pair<int,pair<pii,int> > > q;
	//					step,	pos, col
	q.push(mp(0,mp(mp(0,0),0)));
	pair<pii,int> x,y;
	b[0][0][0]=0;
	while(!q.empty())
	{
		x=q.top().se;
		q.pop();
	//	printf("%d %d %d %d\n",x.first.fi,x.first.se,x.second,b[x.fi.fi][x.fi.se][x.se]);
		if(x.fi==mp(n-1,m-1))
		{
			printf("%d",min(b[n-1][m-1][0],b[n-1][m-1][1]));
			return 0;
		}
		y=go(x.fi,x.se,0,1);
		if(y.first.fi>=0&&b[y.fi.fi][y.fi.se][y.se]>b[x.fi.fi][x.fi.se][x.se]+abs(x.fi.fi-y.fi.fi)+abs(x.fi.se-y.fi.se))
		{
			b[y.fi.fi][y.fi.se][y.se]=b[x.fi.fi][x.fi.se][x.se]+abs(x.fi.fi-y.fi.fi)+abs(x.fi.se-y.fi.se);
			q.push(mp(-b[y.fi.fi][y.fi.se][y.se],y));
		}
		y=go(x.fi,x.se,1,0);
		if(y.first.fi>=0&&b[y.fi.fi][y.fi.se][y.se]>b[x.fi.fi][x.fi.se][x.se]+abs(x.fi.fi-y.fi.fi)+abs(x.fi.se-y.fi.se))
		{
			b[y.fi.fi][y.fi.se][y.se]=b[x.fi.fi][x.fi.se][x.se]+abs(x.fi.fi-y.fi.fi)+abs(x.fi.se-y.fi.se);
			q.push(mp(-b[y.fi.fi][y.fi.se][y.se],y));
		}
		y=go(x.fi,x.se,0,-1);
		if(y.first.fi>=0&&b[y.fi.fi][y.fi.se][y.se]>b[x.fi.fi][x.fi.se][x.se]+abs(x.fi.fi-y.fi.fi)+abs(x.fi.se-y.fi.se))
		{
			b[y.fi.fi][y.fi.se][y.se]=b[x.fi.fi][x.fi.se][x.se]+abs(x.fi.fi-y.fi.fi)+abs(x.fi.se-y.fi.se);
			q.push(mp(-b[y.fi.fi][y.fi.se][y.se],y));
		}
		y=go(x.fi,x.se,-1,0);
		if(y.first.fi>=0&&b[y.fi.fi][y.fi.se][y.se]>b[x.fi.fi][x.fi.se][x.se]+abs(x.fi.fi-y.fi.fi)+abs(x.fi.se-y.fi.se))
		{
			b[y.fi.fi][y.fi.se][y.se]=b[x.fi.fi][x.fi.se][x.se]+abs(x.fi.fi-y.fi.fi)+abs(x.fi.se-y.fi.se);
			q.push(mp(-b[y.fi.fi][y.fi.se][y.se],y));
		}
	}
	printf("-1");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值