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");
}