期望:100 + 20 + 70 = 190

score: 100 + 20 + 60 = 180

总结

T1 小清新题目,还好,就是细节有点多。

T2 背包 \(dp\) ,排序方式有点鬼畜。

T3 神仙题,但70分暴力却很水 = = 。

吃鱼 (fish)

题面

solution

80pts:直接模拟每一秒发生的变化并且用优先队列维护一下。

100pts:发现直接模拟的话,中间会有些时间什么都没有发生,所以可以直接跳过这些没有贡献的时间,只存每只猫吃完鱼之后的时间就好。

code

/*
work by:Ariel_
Knowledge:模拟
Time:O(m)
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#define ll long long
#define rg register
using namespace std;
const int N = 1e5 + 5;
int read(){
    int x = 0,f = 1; char c = getchar();
    while(c < '0'||c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') {x = x*10 + c - '0'; c = getchar();}
    return x*f;
}
int n, m, x, res_fish;
priority_queue<pair<int,int>,vector<pair<int,int> >, greater<pair<int,int> > > q;
int main(){
   //freopen("fish.in", "r", stdin);
   //freopen("fish.out", "w", stdout);
   m = read(), n = read(), x = read();
   for (int i = 1; i <= n; i++) {
   	 int x = read();
	 q.push(make_pair(x, x));
   }
   res_fish = m - n;
   while(!q.empty()) {
   	  int now = q.top().first;
   	  if (now >= x) break;
   	  int tim = q.top().second; q.pop();
   	  if (res_fish){
   	      q.push(make_pair(now + tim, tim));
   	      res_fish--;
      }
   }
   while (!q.empty() && q.top().first <= x) q.pop();
   int is_eating = (int)q.size();  
   printf("%d %d", res_fish, is_eating);
   puts("");
   return 0;
}

01 背包威力加强版 (bag)

题面

solution

按照 \(q - p\) 排完序然后 01 背包即可。

为啥这样排序 ? 坑

code

/*
work by:Ariel_
Knowledge:dp,排序
Time:能过
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#define int long long
#define rg register
using namespace std;
const int MAXN = 1010;
int read(){
    int x = 0,f = 1; char c = getchar();
    while(c < '0'||c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') {x = x*10 + c - '0'; c = getchar();}
    return x*f;
}
int n, m, f[5010];
struct node{int p, q, v;}sub[MAXN];
bool cmp(node x, node y) {
   return (x.q - x.p) < (y.q - y.p);
}
signed main(){
   //freopen("bag.in", "r", stdin);
   //freopen("bag.out", "w", stdout);
   n = read(), m = read();
   for (int i = 1; i <= n; i++) sub[i].p = read(), sub[i].q = read(), sub[i].v = read();
   sort(sub + 1, sub + n + 1, cmp);
   for (int i = 1; i <= n; i++) 
   	 for (int j = m; j >= sub[i].q; j--) 
   	 	 f[j] = max(f[j - sub[i].p] + sub[i].v, f[j]);
   printf("%lld", f[m]);
   puts("");
   return 0;
}

崩 (beng)

题面

前 70 分,模拟就好了。将走过的位置标记一下,然后外部 bfs ,用最大的矩形减去包围内的点就是答案。

正解好像没有诶,听说是个炒鸡麻烦的离散化,坑。。。

/*
work by:Ariel_
Knowledge:
Time:
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#define int long long
#define rg register
using namespace std;
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {-1, 1, 0, 0};
const int MAXN = 4000;
int read(){
    int x = 0,f = 1; char c = getchar();
    while(c < '0'||c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') {x = x*10 + c - '0'; c = getchar();}
    return x*f;
}
int k, mp[MAXN][MAXN], mxl, mxr, x, lmax, rmax, upmax, dmax, Ans;
char opt;
struct node{int x, y;};
queue<node> q;
void bfs(int x, int y) {
   if (mp[x][y]) return;
   q.push((node){x, y});
   while(!q.empty()) {
   	 int nx = q.front().x, ny = q.front().y;
   	 q.pop();
   	 if (mp[nx][ny]) continue; 
	 if (!mp[nx][ny]) {mp[nx][ny] = 1; Ans++;}
	 for (int i = 0; i <= 3; i++) {
	 	int xx = nx + dx[i], yy = ny + dy[i];
	 	if (xx > upmax || xx < dmax || ny <= lmax || ny >= rmax) continue;
	 	if (mp[xx][yy]) continue;
	 	q.push((node){xx, yy});
	 }	
   }
}
signed main(){
   //freopen("beng.in", "r", stdin);
   //freopen("beng.out", "w", stdout); 
   k = read();
   int sx = 1005, sy = 1005;
   lmax = rmax = upmax = dmax = 1005;
   for (int i = 1; i <= k; i++) {
   	   cin >> opt >> x;
   	   if (opt == 'R') {
   	      for (int j = sy; j <= sy + x; j++) mp[sx][j] = 1;
		  rmax = max(rmax, sy + x);
		  sy = sy + x;
	   } 
	   else if (opt == 'L') {
	   	  for (int j = sy; j >= sy - x; j--) mp[sx][j] = 1;
	   	  lmax = min(lmax, sy - x);
	   	  sy = sy - x;
	   }
	   else if (opt == 'D') {
	   	  for (int j = sx; j >= sx - x; j--) mp[j][sy] = 1;
	   	  dmax = min(dmax, sx - x);
	   	  sx = sx - x;
	   }
	   else if (opt == 'U') {
	   	  for (int j = sx; j <= sx + x; j++) mp[j][sy] = 1;
	   	  upmax = max(upmax, sx + x);
	   	  sx = sx + x;
	   } 
   } 
   for (int i = lmax; i <= rmax; i++) bfs(upmax, i), bfs(dmax, i);
   for (int i = dmax; i <= upmax; i++) bfs(i, lmax), bfs(i, rmax);
   printf("%lld", (rmax - lmax + 1) * (upmax - dmax + 1) - Ans);
   puts("");
   return 0;
}

std

#include<bits/stdc++.h>
using namespace std;
#define li long long
#define gc getchar()
#define pc putchar
inline li read(){
	li x = 0,y = 0,c = gc;
	while(!isdigit(c)) y = c,c = gc;
	while(isdigit(c)) x = (x << 1) + (x << 3) + (c ^ '0'),c = gc;
	return y == '-' ? -x : x;
}
void print(li q){
	if(q < 0){
		pc('-');
		q = -q;
	}
	if(q >= 10) print(q / 10);
	pc(q % 10 + '0');
}
li s1 = 19260817,s2 = 23333333,s3 = 998244853,srd;
li rd(){
	return srd = (srd * s1 + s2 + rand()) % s3;
}
int n;
int a[1010],b[1010];
li ans;
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
//l:0 u:1 r:2 d:3
int nw[1010],mn[1010];
struct node{
	int l,r,p;
}p1[1010],p2[1010],q1[1010],q2[1010];
int tot1,tot2,t1,t2;
inline bool operator < (node q,node w){
	return q.p < w.p;
}
#define inf 2000000000
int bj[4010][4010];
int q[17000010][2];
int h,t;
void bf1(){
	int i,j,nx,ny,tx,ty;
	for(i = 1;i <= t1;++i){
		for(j = q1[i].l;j <= q1[i].r;++j) bj[j + 1005][q1[i].p + 1005] = 1;
	}
	for(i = 1;i <= t2;++i){
		for(j = q2[i].l;j <= q2[i].r;++j) bj[q2[i].p + 1005][j + 1005] = 1;
	}
	q[++t][0] = 1;q[t][1] = 1;bj[1][1] = 2;
	while(h < t){
		nx = q[++h][0];ny = q[h][1];
		for(int i = 0;i < 4;++i){
			tx = nx + dx[i];ty = ny + dy[i];
			if(tx >= 1 && tx <= 2008 && ty >= 1 && ty <= 2008 && !bj[tx][ty]){
				bj[tx][ty] = 2;
				q[++t][0] = tx;q[t][1] = ty;
			}
		}
	}
	for(i = 1;i <= 2008;++i) for(j = 1;j <= 2008;++j) if(bj[i][j] != 2) ++ans;
	print(ans);pc('\n');
}
struct lsh{
	int x,id;bool fg,wz;
}ll[10010];
inline bool operator < (lsh q,lsh w){
	return q.x < w.x;
}
int tot,len1[10010],len2[10010],nw1 = 1,nw2 = 1;
void work(){
	int i,j,nx,ny,tx,ty;
	++nw1;++nw2;h = t = ans = 0;memset(bj,0,sizeof(bj));
	for(i = 1;i <= t1;++i){
		for(j = q1[i].l;j <= q1[i].r;++j) bj[j][q1[i].p] = 1;
	}
	for(i = 1;i <= t2;++i){
		for(j = q2[i].l;j <= q2[i].r;++j) bj[q2[i].p][j] = 1;
	}
	q[++t][0] = 1;q[t][1] = 1;bj[1][1] = 2;
	while(h < t){
		nx = q[++h][0];ny = q[h][1];
		for(int i = 0;i < 4;++i){
			tx = nx + dx[i];ty = ny + dy[i];
			if(tx >= 1 && tx <= nw1 && ty >= 1 && ty <= nw2 && !bj[tx][ty]){
				bj[tx][ty] = 2;
				q[++t][0] = tx;q[t][1] = ty;
			}
		}
	}
	for(i = 1;i <= nw1;++i) for(j = 1;j <= nw2;++j) if(bj[i][j] != 2) ans += 1ll * len1[i] * len2[j];
	print(ans);pc('\n');
}
int main(){
	srand(time(0));rd();
	register int i,j;
	char c;
	n = read();
	int nwx = 0,nwy = 0,newx,newy;
	for(i = 1;i <= n;++i){
		c = gc;while(c < 'A' || c > 'Z') c = gc;
		if(c == 'L') a[i] = 0;
		else if(c == 'U') a[i] = 1;
		else if(c == 'R') a[i] = 2;
		else a[i] = 3;
		b[i] = read();
		newx = nwx + dx[a[i]] * b[i];newy = nwy + dy[a[i]] * b[i];
		if(nwx == newx){
			p2[++tot2].l = min(newy,nwy);
			p2[tot2].r = max(newy,nwy);
			p2[tot2].p = newx;
		}
		else{
			p1[++tot1].l = min(newx,nwx);
			p1[tot1].r = max(newx,nwx);
			p1[tot1].p = newy;
		}
		nwx = newx;nwy = newy;
	}
	sort(p1 + 1,p1 + tot1 + 1);sort(p2 + 1,p2 + tot2 + 1);
	q1[0].p = q2[0].p = -inf;
	for(i = 1;i <= tot1;++i){
		if(q1[t1].p == p1[i].p){
			q1[t1].l = min(q1[t1].l,p1[i].l);
			q1[t1].r = max(q1[t1].r,p1[i].r);
		}
		else q1[++t1] = p1[i];
	}
	for(i = 1;i <= tot2;++i){
		if(q2[t2].p == p2[i].p){
			q2[t2].l = min(q2[t2].l,p2[i].l);
			q2[t2].r = max(q2[t2].r,p2[i].r);
		}
		else q2[++t2] = p2[i];
	}
	if(!t1){
		print(q2[1].r - q2[1].l + 1);
		return 0;
	}
	if(!t2){
		print(q1[1].r - q1[1].l + 1);
		return 0;
	}
	
	bool fg = 1;
	for(i = 1;i <= t1;++i) if(q1[i].l < -1000 || q1[i].r > 1000 || q1[i].p < -1000 || q1[i].p > 1000) fg = 0;
	for(i = 1;i <= t2;++i) if(q2[i].l < -1000 || q2[i].r > 1000 || q2[i].p < -1000 || q2[i].p > 1000) fg = 0;
	if(fg){
		bf1();
		return 0;
	}
	
	for(i = 1;i <= t1;++i){
		ll[++tot].x = q1[i].l;ll[tot].id = i;ll[tot].wz = 0;ll[tot].fg = 0;
		ll[++tot].x = q1[i].r;ll[tot].id = i;ll[tot].wz = 1;ll[tot].fg = 0;
	}
	for(i = 1;i <= t2;++i){
		ll[++tot].x = q2[i].p;ll[tot].id = i;ll[tot].wz = 0;ll[tot].fg = 1;
	}
	sort(ll + 1,ll + tot + 1);
	for(i = 1;i <= tot;++i){
		if(i == 1){
			++nw1;
			len1[nw1] = 1;
		} 
		else if(ll[i].x - ll[i - 1].x == 1){
			++nw1;
			len1[nw1] = 1;
		} 
		else if(ll[i].x - ll[i - 1].x > 1){
			++nw1;len1[nw1] = ll[i].x - ll[i - 1].x - 1;
			++nw1;len1[nw1] = 1;
		}
		if(ll[i].fg) q2[ll[i].id].p = nw1;
		else if(ll[i].wz) q1[ll[i].id].r = nw1;
		else q1[ll[i].id].l = nw1;
	}
	
	tot = 0;
	for(i = 1;i <= t2;++i){
		ll[++tot].x = q2[i].l;ll[tot].id = i;ll[tot].wz = 0;ll[tot].fg = 0;
		ll[++tot].x = q2[i].r;ll[tot].id = i;ll[tot].wz = 1;ll[tot].fg = 0;
	}
	for(i = 1;i <= t1;++i){
		ll[++tot].x = q1[i].p;ll[tot].id = i;ll[tot].wz = 0;ll[tot].fg = 1;
	}
	sort(ll + 1,ll + tot + 1);
	for(i = 1;i <= tot;++i){
		if(i == 1){
			++nw2;
			len2[nw2] = 1;
		} 
		else if(ll[i].x - ll[i - 1].x == 1){
			++nw2;
			len2[nw2] = 1;
		} 
		else if(ll[i].x - ll[i - 1].x > 1){
			++nw2;len2[nw2] = ll[i].x - ll[i - 1].x - 1;
			++nw2;len2[nw2] = 1;
		}
		if(ll[i].fg) q1[ll[i].id].p = nw2;
		else if(ll[i].wz) q2[ll[i].id].r = nw2;
		else q2[ll[i].id].l = nw2;
	}
	work();
	return 0;
}