听说今后会两天一考……
嘛,尽量把题目都整理下吧
T1
大意:
n种颜料,只能成套买,每套50ml;另有灰色颜料只可由3种不同颜料合成。给出每种颜料需要多少,求最少几套颜料可满足要求
正解:贪心,每次取最多的三种颜料合成
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 100 + 50;
int cnt,a[MAXN],n,x,m,tmp[MAXN],maxn;
bool cmp(int a,int b)
{
return a > b;
}
int main()
{
while(scanf("%d",&n) && n)
{
cnt = 1;maxn = 0;
for(int i = 1;i <= n;i ++)
{
scanf("%d",&tmp[i]);
}
sort(tmp + 1,tmp + n + 1,cmp);
cnt = tmp[1]/50 + 1;
if(tmp[1]%50 == 0)cnt --;
for(int i = 1;i <= n;i ++)
{
a[i] = cnt * 50 - tmp[i];
}
scanf("%d",&m);
while(m)
{
if(!a[3])
{
for(int i = 1;i <= n;i ++)a[i] += 50;
cnt ++;
}
else
{
a[1] --;
a[2] --;
a[3] --;
m --;
sort(a + 1,a + n + 1,cmp);
}
}
printf("%d\n",cnt);
}
return 0;
}
打出来更像模拟……毕竟数据范围太小了……
考场上误以为满足电池的性质……二分答案……于是悲惨的挂了……
T2
大意:
X*Y的矩阵上分布n个敌人,给出每个敌人的坐标和出发点、到达点,求在离敌人最短距离最大化的前提下,起点至终点的最短距离
对于第二问,因为是曼哈顿距离所以在最小距离的限制下BFS就可以了
对于第一问:预处理出地图上每个点距敌人的最短距离
那复杂度不是n*X*Y的吗?
然而每个格子距敌人的最短距离仅会由离他最近的敌人确定……
再加上BFS神奇的宽度优先性质,最先搜到的距离一定是每个格子的最短距离……
然后二分答案,在每个距离限制下BFS一遍判断能否由起点到达终点
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN = 1000 + 50;
struct zt
{
int x,y,step;
};
queue <zt> q;
int N,n,m,map[MAXN][MAXN],x,y,x0,y0,x1,y1;
int mu[] = {0,1,-1,0},
mr[] = {1,0,0,-1};
void init()
{
while(!q.empty())
{
zt u = q.front();
q.pop();
for(int i = 0;i < 4;i ++)
{
int xx = u.x + mu[i];
int yy = u.y + mr[i];
if(xx >= 0 && yy >= 0 && xx < n && yy < m && map[xx][yy] == -1)
map[xx][yy] = map[u.x][u.y] + 1,q.push((zt){xx,yy});
}
}
}
bool vis[MAXN][MAXN];
int C(int x)
{
if(x1 == x0 && y1 == y0)return 0;
memset(vis,0,sizeof(vis));
vis[x0][y0] = true;
while(!q.empty())q.pop();
q.push((zt){x0,y0});
while(!q.empty())
{
zt u = q.front();
q.pop();
for(int i = 0;i < 4;i ++)
{
int xx = u.x + mu[i];
int yy = u.y + mr[i];
if(xx >= 0 && yy >= 0 && xx < n && yy < m && !vis[xx][yy] && map[xx][yy] >= x)
{
q.push((zt){xx,yy,u.step + 1});
vis[xx][yy] = true;
if(xx == x1 && yy == y1)
{
return u.step + 1;
}
}
}
}
return -1;
}
int step;
int main()
{
freopen("escape.in","r",stdin);
freopen("escape.out","w",stdout);
scanf("%d%d%d",&N,&n,&m);
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
memset(map,-1,sizeof(map));
for(int i = 1;i <= N;i ++)
{
scanf("%d%d",&x,&y);
q.push((zt){x,y});
map[x][y] = 0;
}
init();
int L = -1,R = map[x0][y0] + 1;
while(R - L > 1)
{
int mid = L + R >> 1;
int temp = C(mid);
if(temp != -1)L = mid,step = temp;
else R = mid;
}
printf("%d %d",max(0,L),step);
fclose(stdin);
fclose(stdout);
return 0;
}
一开始看错了题……以为是到每个敌人曼哈顿距离最大的点……
还很兴奋的写了半天二维前缀和……当然最后这题是弃了Orz
然后一听题解发现这题才最可做……
T3
poj1837
DP,没写正解
考场上打了个奇怪的gcd+爆搜然而跪了……
Tips:
考试策略还是有很大问题,下次争取先把暴力分都拿到……
要是继续考这分初赛都要跪
怎么办药丸药丸QAQ