HGOI 20200801

8月的第一天

这套题没打完就走了

只写了T1正解

其他两题放一下STD

T1 八数码

#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 = 100010 ;

int cnt = 0 ;
queue <pair<int, int> > q ;
vector <int> a, b ;
map <int, int> hsh ;

int cgt(vector <int> a) {
	int num = 0 ;
	rep(i, 0, 8) num = num * 10 + a[i] ;
	return num ;
}

vector <int> bck(int num) {
	vector <int> a ;
	rep(i, 0, 8) {
		a.pb(num % 10) ;
		num /= 10 ;
	}
	reverse(a.begin(), a.end()) ;
	return a ;
}

int get(int num) {
	vector <int> a = bck(num) ;
	rep(i, 0, 8) if (a[i] == 0) return i ;
	return 0 ;
}

/* 
op = 1 : up
op = 2 : down 
op = 3 : left
op = 4 : right
*/

int check(int x, int pos, int op) {
	if (op == 1 && pos <= 2) return false ;
	if (op == 2 && pos >= 6) return false ;
	if (op == 3 && pos % 3 == 0) return false ;
	if (op == 4 && pos % 3 == 2) return false ;
	return true ; 
}

void move(int x, int pos, int op, int stp) {
	vector <int> a = bck(x) ;
	if (op == 1) swap(a[pos], a[pos - 3]) ;
	if (op == 2) swap(a[pos], a[pos + 3]) ;
	if (op == 3) swap(a[pos], a[pos - 1]) ;
	if (op == 4) swap(a[pos], a[pos + 1]) ;
	int newx = cgt(a) ;
	if (hsh[newx]) return ;
	hsh[newx] = ++cnt ;
	q.push(mp(newx, stp + 1)) ;
}

signed main() {
	freopen("eight.in", "r", stdin) ;
	freopen("eight.out", "w", stdout) ;
	rep(i, 0, 8) a.pb(0), b.pb(0) ;
	rep(i, 0, 8) scanf("%d", &a[i]) ;
	rep(i, 0, 8) scanf("%d", &b[i]) ;
	int va = cgt(a), vb = cgt(b) ;
	q.push(mp(va, 0)) ; hsh[va] = ++cnt ;
	while (!q.empty()) {
		int x = q.front().fi, stp = q.front().se ; q.pop() ;
	//	cout << x << endl ;
		vector <int> xx = bck(x) ;
	//	rep(i, 0, 8) cout << xx[i] << " " ; cout << endl ;
		if (x == vb) {
			printf("%d
", stp) ;
			exit(0) ;
		}
		int pos = get(x) ;
		if (check(x, pos, 1)) move(x, pos, 1, stp) ;
		if (check(x, pos, 2)) move(x, pos, 2, stp) ;
		if (check(x, pos, 3)) move(x, pos, 3, stp) ;
		if (check(x, pos, 4)) move(x, pos, 4, stp) ;
	}
	printf("-1
") ;
	return 0 ;
}

T2 多段线性函数

#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
typedef long long ll;
vector <int> q;
int main() {
    freopen("linear.in", "r", stdin);
    freopen("linear.out", "w", stdout);
    int n, x, i, L, R;
    ll sum = 0, cnt, ret = 1ll << 60, cur;
    scanf("%d", &n); cnt = -n;
    while (n--) {scanf("%d", &x); q.push_back(x); sum += x; scanf("%d", &x); q.push_back(x);}
    sort(q.begin(), q.end());
    for (i = 0; i < q.size(); ++i) {
        sum -= q[i]; ++cnt; cur = sum + cnt * q[i];
        if (cur < ret) {ret = cur; L = q[i];}
        else if (cur == ret) R = q[i];
    }
    printf("%d %d
", L, R);
    return 0;
}

T3 模模塔

#include <bits/stdc++.h>
typedef long long LL;
const int MAXN = 100100;
const int MOD = 123456789;
const int K = 330;
int n;
int a[MAXN], b[MAXN], c[MAXN];
int sum[K][MAXN];
void rd(int &t) {
	t = 0;
    char p = getchar();
    while (p < 48 || p > 57) p = getchar();
    do {(t *= 10) += p - 48; p = getchar();} while (p > 47 && p < 58);
}
int main(){
	freopen("mmt.in", "r", stdin);
	freopen("mmt.out", "w", stdout);
	rd(n);
	for (int i = 1; i <= n; ++i) rd(a[i]);
	for (int i = 0; i < n; ++i) rd(b[i]);
	for (int i = 1; i < K; ++i)
		for (int j = 0; j < n; ++j){
			sum[i][j] = (j >= i ? sum[i][j - i] : 0) + b[j];
			if (sum[i][j] >= MOD) sum[i][j] -= MOD;
		}
	for (int i = 1; i <= n; ++i){
		for (int j = 1; j <= K && j <= i; ++j)
			c[i] = (c[i] + (LL)a[i / j] * b[i % j]) % MOD;
		for (int l = K + 1, r = K + 1; l <= i; l = r + 1){
			int t = i / l; r = i / t;
			c[i] = (c[i] + (LL)a[t] * (MOD + sum[t][i - t * l] - (i > t * (r + 1) ? sum[t][i - t * (r + 1)] : 0))) % MOD;
		}
	}
	for (int i = 1; i <= n; ++i)
		printf("%d
", c[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/harryhqg/p/13413200.html