HGOI 20190711

Posted harryhqg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HGOI 20190711相关的知识,希望对你有一定的参考价值。

水题都做不好,看来凉了

T1 音量调节(changingsounds)

这是个小菜鸡题

只需要 (dp) 一波就行(理论上都不是 (dp)

(dp[i][j]) 表示第 (i) 首歌曲能否达到 (j) 的音量

(dp[n][i]=1) 找到 (i) 最大的

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define siz(a) (int)a.size()
#define pb push_back
#define mp make_pair
#define ll long long
#define fi first
#define se second

const int N = 60 ;

int n, b, e ;
int a[N], f[N][1010] ;

signed main() {
//	freopen("changingsounds.in", "r", stdin) ;
//	freopen("changingsounds.out", "w", stdout) ;
	scanf("%d%d%d", &n, &b, &e) ;
	rep(i, 1, n) scanf("%d", &a[i]) ;
	f[0][b] = 1 ;
	rep(i, 1, n)
	rep(j, 0, e) {
		if (j - a[i] >= 0) f[i][j] |= f[i - 1][j - a[i]] ;
		if (j + a[i] <= e) f[i][j] |= f[i - 1][j + a[i]] ;
	}
	int ans = -1 ;
	per(i, e, 0) 
	if (f[n][i]) {
		ans = i ;
		break ;
	}
	if (ans == -1) printf("%d
", ans) ;
	else printf("%d
", ans) ;
	return 0 ;
}

T2 旅行(journey)

这个题目稍难些

可以发现前50分按照他那个公式处理就行了(送的真多)

对于剩下的50分,你会发现公式是错的(doge)
会有 (X) 挡路,所有需要越过 (X)
而每越过一个 (X),你的距离就会增加 (2)
由于没有连续的对角线挡路,所以只要考虑多少对 ((i,j))(X) 挡住了。

但是刚开始只想到了在同一行、列内如果挡住了会有需要绕过 (X) 的情况,
但其实如果不同的两行、列之间,所走的曼哈顿路径也被 (X) 挡住了,
那也是需要进行绕路的。

#include <bits/stdc++.h>
using namespace std ;

#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define siz(a) (int) a.size()
#define pb push_back
#define mp make_pair
#define ll long long
#define fi first
#define se second

const int N = 1010;

char ch[N][N];
int x[N], y[N], n, m;

int main() {
	scanf("%d%d", &n, &m);
	rep(i, 0, n - 1) 
	rep(j, 0, m - 1)
	scanf(" %c", &ch[i][j]);
	rep(i, 0, n - 1) {
		y[i] = -1;
		rep(j, 0, m - 1) {
			if (ch[i][j] == ‘X‘) {
				y[i] = j;
				break;
			}
		}
	}
	rep(j, 0, m - 1) { 
		x[j] = -1;
		rep(i, 0, n - 1) {
			if (ch[i][j] == ‘X‘) {
				x[j] = i;
				break;
			}
		}
	}
	ll sum = 0;
	rep(i, 0, n - 1) 
	rep(j, i + 1, n - 1) 
	sum += (ll) (m - (y[i] >= 0)) * (m - (y[j] >= 0)) * (j - i) * 2;
	rep(i, 0, m - 1) 
	rep(j, i + 1, m - 1) 
	sum += (ll) (n - (x[i] >= 0)) * (n - (x[j] >= 0)) * (j - i) * 2;
	rep(i, 0, m - 1) {
		if (x[i] == -1) continue;
		int below = n - 1 - x[i], above = x[i];
		sum += (ll) (below) * above * 4;
		rep(j, i + 1, m - 1) {
			if (x[j] == -1 || x[j] > x[j - 1]) break;
			above = x[j];
			sum += (ll) (below) * above * 4;
		}
        above = x[i];
        per(j, i - 1, 0) {
			if (x[j] == -1 || x[j] > x[j + 1]) break;
			above = x[j];
			sum += (ll) (below) * above * 4;
		}
	}
	rep(i, 0, n - 1) {
		if (y[i] == -1) continue;
		int below = y[i], above = m - 1 - y[i];
		sum += (ll) (below) * above * 4;
		rep(j, i + 1, n - 1) {
			if (y[j] == -1 || y[j] < y[j - 1]) break;
			above = m - 1 - y[j];
			sum += (ll) (below) * above * 4;
		}
        above = m - 1 - y[i];
        per(j, i - 1, 0) {
			if (y[j] == -1 || y[j] < y[j + 1]) break;
			above = m - 1 - y[j];
			sum += (ll) (below) * above * 4;
        }
	}
	double ans = 0;
	rep(i, 0, n - 1) ans += m - (y[i] >= 0);
	ans = ans * ans;
	ans = sum / ans;
	printf("%.4f
", ans);
	return 0;
}

T3 舞蹈课(dancinglessons)

也是个小傻逼题

用链表维护相邻关系

把相邻的BG扔进小根堆,每次查出最小的相邻把他们拎出来

然后剩旁边两边合并,如果也是BG那个也加入

结果a,b有一个地方打错GG了./气死

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define siz(a) (int)a.size()
#define pb push_back
#define mp make_pair
#define ll long long
#define fi first
#define se second

const int iinf = 0x3f3f3f3f ;
const int N = 200010 ;

int n, cnt ;
string s ;
int a[N], b[N], suf[N], pre[N] ;

struct group {
	int x, y, del ;
} ;

bool operator < (group a, group b) {
	if (a.del != b.del) return a.del > b.del ;
	else return a.x > b.x ;
}

priority_queue <group> q ;
vector <pair<int, int> > ans ;

signed main() {
//	freopen("dancinglessons.in", "r", stdin) ;
//	freopen("dancinglessons.out", "w", stdout) ;
	scanf("%d", &n) ;
	cin >> s ;
	rep(i, 1, n) a[i] = (s[i - 1] == ‘B‘) ? 1 : 0 ;
	rep(i, 1, n) cnt += a[i] ;
	cnt = min(cnt, n - cnt) ;
	rep(i, 1, n) scanf("%d", &b[i]) ;
	rep(i, 1, n - 1) suf[i] = i + 1 ;
	rep(i, 2, n) pre[i] = i - 1 ;
	suf[n] = pre[1] = 0 ; b[0] = iinf ;
	rep(i, 1, n - 1) if (a[i] != a[i + 1]) q.push((group) {i, i + 1, abs(b[i] - b[i + 1])}) ;
	rep(i, 1, cnt) {
		while (!q.empty()) {
			group c = q.top() ; q.pop() ;
			if (b[c.x] == iinf || b[c.y] == iinf) continue ;
			ans.pb(mp(c.x, c.y)) ;
			suf[pre[c.x]] = suf[c.y] ; 
			pre[suf[c.y]] = pre[c.x] ;
			int u = pre[c.x], v = suf[c.y] ;
			if (a[u] != a[v]) q.push((group) {u, v, abs(b[u] - b[v])}) ;
			pre[c.x] = suf[c.x] = -1 ;
			pre[c.y] = suf[c.y] = -1 ;
			b[c.x] = b[c.y] = iinf ;
		}
	}
	printf("%d
", siz(ans)) ;
	rep(i, 0, siz(ans) - 1) printf("%d %d
", ans[i].fi, ans[i].se) ;
	return 0 ;
}






以上是关于HGOI 20190711的主要内容,如果未能解决你的问题,请参考以下文章

hgoi#20191115

hgoi#20190514

hgoi#20191109

hgoi#2019/2/16--t2--friend

HGOI 20181028 题解

HGOI 20190828 题解