• 11.19模拟


    T1

    基本上跟石子合并一样。区别可能就是需要维护一下当前已有的集合,可以直接用bitset硬上,也可以预处理,数据小基本上没区别。

    #include <cstdio>
    #include <cstring>
    #include <bitset>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 603;
    int n, nn, mx;
    int a[maxn];
    bitset<303> s[maxn][maxn];
    int dp[maxn][maxn];
    int g[maxn][maxn];
    int main() {
    	freopen("merge.in", "r", stdin);
    	freopen("merge.out", "w", stdout);
    	cin >> n;
    	nn = n << 1;
    	for (int i = 1; i <= n; ++i) {
    		scanf("%d", &a[i]);
    		a[i + n] = a[i];
    		s[i][i][a[i]] = 1;
    		s[i + n][i + n][a[i]] = 1;
    		g[i][i] = 1;
    		g[n + i][n + i] = 1;
    		if (a[i] > mx) mx = a[i];
    	}
    	for (register int len = 2; len <= n; ++len) {
    		for (register int l = 1; l + len - 1 <= nn; ++l) {
    			register int r = l + len - 1;
    			for (register int k = l; k < r; ++k) {
    				if (dp[l][k] + dp[k + 1][r] + g[l][k] * g[k + 1][r] > dp[l][r]) {
    					dp[l][r] = dp[l][k] + dp[k + 1][r] + g[l][k] * g[k + 1][r];
    					s[l][r] = s[l][k] | s[k + 1][r];
    				}
    			}
    			g[l][r] = 0;
    			for (register int i = 1; i <= mx; ++i) if (s[l][r][i]) g[l][r]++;
    		}
    	}
    	int ans = 0;
    	for (int l = 1; l + n - 1 <= nn; ++l) if (dp[l][l + n - 1] > ans) ans = dp[l][l + n - 1];
    	cout << ans << '
    ';
    	return 0;
    }
    

    T2

    找规律一定要沉住气,不要着急不要慌,把问题考虑全面,只要用心找一定是能找出来的。

    按照人类的思维,一定是把所有城镇都堆在一起尽量堆成一个六边形是最优的,计算方式数据范围(N = 6 imes frac{K(K + 1)}{2})已经给了提示了。

    通过这个式子你很容易知道当前能堆成的最大六边形的边长是多少,然后把边角料尽量往边上放即可,在边上连续放不会增加答案,但如果在一条新边上放就会使答案+1。

    #include <bits/stdc++.h>
    using namespace std;
    
    long long n;
    inline long long Calc(long long x) {
    	return 6 * x * (x + 1) / 2 + 1;
    }
    
    int main() {
    	freopen("wall.in", "r", stdin);
    	freopen("wall.out", "w", stdout);
    	cin >> n;
    	long long l = 0, r = 1000000000, mid;
    	while (l <= r) {
    		mid = (l + r) >> 1;
    		if (Calc(mid) < n) l = mid + 1;
    		else r = mid - 1;
    	}
    	long long len = l + 1;
    	if (n == 6 * len * (len - 1) / 2 + 1) {
    		printf("%lld
    ", len * 6);
    		return 0;
    	}
    	long long ans = (len - 1) * 6 + 1;
    	long long res = 6 * (len - 2) * (len - 1) / 2 + 1;
    	ans += (n - res) / (len - 1);
    	cout << ans << '
    ';
    	return 0;
    }
    

    T3

    首先考虑 (f_i leq i) 的情况。

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    inline int read() {
    	int s = 0, w = 1;
    	char c = getchar();
    	while (c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); }
    	while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    	return s * w;
    }
    const int maxn = 1e5 + 10;
    struct edge {
    	int nex;
    	int to;
    } e[maxn << 1];
    int n;
    int tot;
    int a[maxn];
    int c[maxn];
    int d[maxn];
    int f[maxn];
    int mx[maxn];
    int cmx[maxn];
    int head[maxn];
    void Add(int u, int v) {
    	e[++tot] = (edge) { head[u], v }, head[u] = tot;
    }
    int dfsclock;
    int scc;
    int top;
    int stk[maxn];
    int dfn[maxn];
    int low[maxn];
    int bel[maxn];
    int siz[maxn];
    int from[maxn];
    bool vis[maxn];
    vector<int> hav[maxn];
    void Tarjan(int u) {
    	dfn[u] = low[u] = ++dfsclock;
    	stk[++top] = u;
    	for (int i = head[u]; i; i = e[i].nex) {
    		int v = e[i].to;
    		if (!dfn[v]) {
    			Tarjan(v);
    			low[u] = min(low[u], low[v]);
    		}
    		else if (!bel[v]) low[u] = min(low[u], dfn[v]);
    	}
    	if (dfn[u] == low[u]) {
    		scc++;
    		while (true) {
    			int x = stk[top--];
    			hav[scc].push_back(x);
    			bel[x] = scc;
    			siz[scc]++;
    			if (u == x) break;
    		}
    	}
    }
    signed main() {
    	freopen("goods.in", "r", stdin);
    	freopen("goods.out", "w", stdout);
    	n = read();
    	for (int i = 1; i <= n; ++i) {
    		from[i] = i;
    		f[i] = read(), c[i] = read(), d[i] = read(), a[i] = read();
    	}
    	for (int i = 1; i <= n; ++i) {
    		int v = f[i];
    		if (d[v] - c[i] > mx[v]) from[v] = i, cmx[v] = mx[v], mx[v] = d[v] - c[i];
    		else if (d[v] - c[i] > cmx[v]) cmx[v] = d[v] - c[i];
    	}
    	for (int i = 1; i <= n; ++i) Add(from[i], i);
    	for (int i = 1; i <= n; ++i) if (!dfn[i]) Tarjan(i);
    	int ans = 0;
    	for (int i = 1; i <= scc; ++i) {
    		if (siz[i] == 1) {
    			ans += a[hav[i][0]] * mx[hav[i][0]];
    			continue;
    		}
    		int res = INT_MAX;
    		int tmp = 0;
    		for (int j = 0; j < (int) hav[i].size(); ++j) {
    			int x = hav[i][j];
    			tmp += mx[x] * a[x];
    			if (mx[x] - cmx[x] < res) res = mx[x] - cmx[x];
    		}
    		ans += tmp - res;
    	}
    	cout << ans << '
    ';
    	return 0;
    }
    

    T4

    暴力就是(n^2)枚举答案,然后dfs暴力删,如果能删完整个串即为答案。别人这么写都是50分,不知道为啥我是20分,可能是没剪枝的问题。

    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    const int maxn = 1e5 + 10;
    const int base = 31;
    const int mod1 = 998244353;
    const int mod2 = 1000000007;
    int n;
    char s[maxn];
    bool del[maxn];
    int stk[maxn * 500];
    int top;
    bool dfs(int cnt, ull now, int len) {
    	if (!cnt) return 1;
    	int flag = 0;
    	for (int l = 1, r; l <= n; ++l) {
    		if (del[l]) continue;
    		int rcnt = 0;
    		ull res = 0;
    		r = l;
    		int rcd = top;
    		while (rcnt < len && r <= n) {
    			while (del[r] && r <= n) r++;
    			if (r > n) break;
    			res = res * base + s[r] - 'a' + 1;
    			stk[++top] = r;
    			rcnt++;
    			if (rcnt < len) r++;
    		}
    		if (r > n || rcnt < len) {
    			while (top > rcd) top--;
    			break;
    		}
    		if (res == now) {
    			for (register int i = rcd + 1; i <= top; ++i) del[stk[i]] = 1;
    			flag |= dfs(cnt - len, now, len);
    			while (top > rcd) del[stk[top--]] = 0;	
    		}
    		else {
    			while (top > rcd) top--;
    		}
    	}
    	return flag;
    }
    int main() {
    	freopen("string.in", "r", stdin);
    	freopen("string.out", "w", stdout);
    	int T;
    	cin >> T;
    	while (T--) {
    		memset(del, 0, sizeof del);
    		scanf("%s", s + 1);
    		n = strlen(s + 1);
    		register int flag = 0;
    		register int L = 0, R = 0;
    		for (register int len = 1; len <= n; ++len) {
    			ull res = 0;
    			ull tmp = 0;
    			for (register int l = 1; l + len - 1 <= n; ++l) {
    				register int r = l + len - 1;
    				res = 0;
    				for (int i = l; i <= r; ++i) res = res * base + s[i] - 'a' + 1;
    				register int op = 0;
    				op |= dfs(n, res, len);
    				if (op && !flag) { flag = 1, tmp = res, L = l, R = r; }
    				else if (op && flag && tmp > res) { res = tmp, L = l, R = r; }
    			}
    			if (flag) break;
    		}
    		if (flag) {
    			for (register int i = L; i <= R; ++i) printf("%c", s[i]);
    		}
    		cout << '
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    各种浏览器(IE,Firefox,Chrome,Opera)COOKIE修改方法[转]
    C#中Socket 和 Tcp 连接的区别
    [转]OpenSSL RSA加解密 (.Net公钥加密/ Linux端私钥解密)
    部分操作系统下的Socket连接数2000到4000左右限制
    安装程序制作软件Inno Setup
    C#中线程占用内存过大解决方法
    Question from one example in Item 5 《Effective C#》
    软件测试基本概念 覆盖率
    C++中的内存管理 (转自:http://www.cnblogs.com/drwilliam/archive/2005/11/12/274937.html)
    Debug DataBinding
  • 原文地址:https://www.cnblogs.com/Zfio/p/14005332.html
Copyright © 2020-2023  润新知