• Codeforces Round #610 (Div. 2) 题解


    Temporarily unavailable

    [Time Limit: 1 squad Memory Limit: 256 MB ]

    直接计算出 ([c-r, c+r])([a, b]) 中的范围有多大,然后减掉就可以了。

    view
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pb         push_back
    #define  pii        pair<int, int>
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 1e5 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
    
    int n, m;
    int cas, tol, T;
    
    int main() {
    	scanf("%d", &T);
    	while(T--) {
    		ll a, b, c, r, ans;
    		scanf("%lld%lld%lld%lld", &a, &b, &c, &r);
    		if(a>b)	swap(a, b);
    		ans = b-a;
    		ll over = max(a, min(c+r, b)) - min(b, max(c-r, a));
    		printf("%lld
    ", ans-over);
    	}
    	return 0;
    }
    

    K for the Price of One (Hard Version)

    [Time Limit: 2 squad Memory Limit: 256 MB ]

    首先肯定是买最便宜的,由于有 (k) 个只能买 (k) 个,所以可以看成有两种策略,买 (1) 个和买 (k) 个,然后用 (dp[i]) 表示买了前 (i) 个物品的最少花费,然后看给出的钱可以买多少个。

    view
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pb         push_back
    #define  pii        pair<int, int>
     
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 2e5 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
     
    int n, m, k;
    int cas, tol, T;
     
    ll dp[maxn];
    int a[maxn];
     
    int main() {
    	scanf("%d", &T);
    	while(T--) {
    		scanf("%d%d%d", &n, &m, &k);
    		for(int i=1; i<=n; i++)	scanf("%d", &a[i]);
    		for(int i=1; i<=n; i++)	dp[i] = INF;
    		dp[0] = 0;
    		sort(a+1, a+1+n);
    		for(int i=1; i<=n; i++) {
    			if(i-k>=0)
    				dp[i] = min(dp[i-1], dp[i-k])+a[i];
    			else
    				dp[i] = dp[i-1]+a[i];
    		}
    		ll ans = 0;
    		for(int i=n; i>=1; i--) {
    			if(dp[i] <= m) {
    				ans = i;
    				break;
    			}
    		}
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }
    

    Petya and Exam

    [Time Limit: 2 squad Memory Limit: 256 MB ]

    由于有一个限制时间 (t_i),那么我可以按限制时间 (t_i) 排序来完成每一个作业。

    (p[i]) 表示完成 (i) 个作业需要的时间,那么我想要完成这 (i) 个作业,我所用的时间必须在 (t_{i+1}) 以内,这些是必须要完成的作业。

    接下来还有一部分剩下的时间,我可以用这些剩余的时间去贪心完成还没到达限制时间的作业,每次先完成简单的,在完成难的。

    view
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pb         push_back
    #define  pii        pair<int, int>
     
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 2e5 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
     
    ll n, m;
    int cas, tol, T;
    
    struct Node {
    	ll a, b, p;
    	bool operator < (Node c) const {
    		return b<c.b;
    	}
    } node[maxn];
    ll p[maxn], a[2];
    
    ll solve(ll time, ll x, ll y) {
    	ll cnt = 0;
    	ll oka = min(x, time/a[0]);
    	cnt += oka;
    	time -= oka*a[0];
    	ll okb = min(y, time/a[1]);
    	cnt += okb;
    	return cnt;
    }
    
    int main() {
    	scanf("%d", &T);
    	while(T--) {
    		scanf("%lld%lld%lld%lld", &n, &m, &a[0], &a[1]);
    		for(int i=1, x; i<=n; i++) {
    			scanf("%lld", &node[i].p);
    			node[i].a = a[node[i].p];
    		}
    		for(int i=1; i<=n; i++) {
    			scanf("%lld", &node[i].b);
    		}
    		p[0] = 0;
    		sort(node+1, node+1+n);
    		node[n+1].b = m+1;
    		for(int i=1; i<=n; i++)	p[i] = p[i-1]+node[i].a;
    		ll ans = 0, cnt[2] = {0};
    //		for(int i=1; i<=n; i++)	printf("%d%c", node[i].a, i==n ? '
    ':' ');
    //		for(int i=1; i<=n; i++)	printf("%d%c", node[i].b, i==n ? '
    ':' ');
    //		for(int i=1; i<=n; i++)	printf("%d%c", p[i], i==n ? '
    ':' ');
    //		cout << "=====" << endl;
    		for(int i=n; i>=0; i--) {
    			if(p[i] < node[i+1].b)
    				ans = max(ans, i+solve(node[i+1].b-p[i]-1, cnt[0], cnt[1]));
    			cnt[node[i].p]++;
    		}
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }
    

    Enchanted Artifact

    [Time Limit: 1 squad Memory Limit: 256 MB ]

    表示 (D、E) 题意一直都没读懂,所以这里也讲一下题意。

    这是一题交互题,也就是一问一答的形式。题意想要让你猜一个全由 (a、b) 组成的字符串,每次你输出一个字符串,题目返回你的字符串和题目的字符串二者之间的编辑距离,要求最多只能问 (n+2) 次,并且每次询问的字符串长度不可以超过 (300)

    第一次给出一个字符串 (a),获得它和答案字符串的编辑距离 (n)。考虑如下事情:如果答案字符串存在一个 (a),那么这个 (a) 一定不变化,只要在两侧插入其他字符即可,那么答案字符串长度就是 (n+1)。如果不存在一个 (a),那么这个 (a) 一定要通过一次操作变成 (b),然后在两侧加入其他字符,则答案字符串长度就是 (n)

    那么第二步我可以输出长度为 (n+1) 并且全为 (a) 的字符,获得两者的编辑距离 (m),那么如果 (m == n+1),答案就一定是第二种,否则就一定是第一种。

    此时我们就获得了答案字符串的字符长度和全为 (a) 时的编辑距离。所以此时的编辑距离可以理解成当前字符串和答案字符串 (s[i] eq t[i]) 的个数。所以我只要操作每一位,把每一位从 (a) 换成 (b),看编辑距离会不会变小,就知道了这一位是不是和答案字符串相同了。

    view
    /*************************************************************** 
        > File Name        : e.cpp
        > Author           : Jiaaaaaaaqi
        > Created Time     : 2019/12/28 19:37:44
     ***************************************************************/
    
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pb         push_back
    #define  pii        pair<int, int>
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 1e5 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
    
    int n, m;
    int cas, tol, T;
    
    pii solve() {
    	cout << "a" << endl;
    	cin >> n;
    	if(n == 300) {
    		for(int i=1; i<=300; i++)	cout << "b";
    		cout << endl;
    		exit(0);
    	}
    	string ans = "";
    	for(int i=0; i<=n; i++)	ans += 'a';
    	cout << ans << endl;
    	cin >> m;
    	if(m == n+1) {
    		for(int i=1; i<=n; i++)	cout << "b";
    		cout << endl;
    		exit(0);
    	} else {
    		return {n+1, m};
    	}
    }
    
    int main() {
    	// freopen("in", "r", stdin);
    	pii pa = solve();
    	int len = pa.fi, ans = pa.se;
    	string ask;
    	for(int i=1; i<=len; i++)	ask += 'a';
    	for(int i=0; ans&&i<len; i++) {
    		ask[i] = 'b';
    		cout << ask << endl;
    		cin >> n;
    		if(n < ans)	ans = n;
    		else	ask[i] = 'a';
    	}
    	cout << ask << endl;
    	return 0;
    }
    

    The Cake Is a Lie

    [Time Limit: 2 squad Memory Limit: 256 MB ]

    把一个 (n) 边形割成 (n-2) 个三角形,给出这 (n-2) 个三角形三个顶点标号,让你构造出 (p、q) 数组,(p) 数组表示这个 (n) 边形顺时针或者逆时针走一圈各个点的标号,(q) 数组表示切割三角形的顺序。

    分成两步来做,第一步确定这个 (n) 边形的标号。我们考虑 (n) 边形的 (n) 条边一定是在且只在一个三角形内,而通过切割后出现的边,则一定会使用两次。

    那么把三角形的边存起来,然后看对于每一个顶点 (u),若存在一个从 (u)(v) 的边,则说明 (u-v) 这条边在一个三角形内出现过,那么只要找到每个 (u) 和其相连的且只出现一次的 (v),把 (v) 放在 (u) 两侧即可,然后通过 (dfs) 一个一个搜出来就可以了。

    对于第二步更加简单,想要切下来一个三角形,那么这个三角形一定是两个边在最外侧,一个边还没切割出来,然后去切割这还没被切割出来的边,那么只要通过拓扑排序类似的方法来一个个切就可以了。

    view
    /*************************************************************** 
        > File Name        : e.cpp
        > Author           : Jiaaaaaaaqi
        > Created Time     : 2019/12/28 20:48:26
     ***************************************************************/
    
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pb         push_back
    #define  pii        pair<int, int>
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 1e5 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
    
    int n, m;
    int cas, tol, T;
    
    vector<int> g[maxn];
    int p[maxn], q[maxn], pos[maxn];
    bool vis[maxn];
    struct E {
    	int a, b, c, cnt;
    } e[maxn];
    
    void put(int u, int v) {
    	if(pos[v])	return ;
    	int x = pos[u], y;
    	y = (x-1==0 ? n : x-1);
    	if(!p[y]) {
    		p[y] = v;
    		pos[v] = y;
    		return ;
    	}
    	y = (x+1==n+1 ? 1 : x+1);
    	if(!p[y]) {
    		p[y] = v;
    		pos[v] = y;
    		return ;
    	}
    }
    
    void dfs(int u) {
    	if(vis[u])	return ;
    	vis[u] = true;
    	for(int i=0, cnt=1; i<g[u].size()-1; i++) {
    		if(g[u][i] == g[u][i+1])	cnt++;
    		else {
    			if(cnt == 1)	put(u, g[u][i]), dfs(g[u][i]);
    			cnt = 1;
    		}
    	}
    }
    
    map<pii, int> mp, mp2;
    vector<int> vv[maxn*10];
    
    void topu() {
    	queue<int> Q;
    	int ans = 0;
    	for(int i=1; i<=n; i++)	mp2[{min(p[i], p[i%n+1]), max(p[i], p[i%n+1])}] = 1;
    	for(int i=1; i<=m; i++)	vis[i] = 0;
    	for(int i=1; i<=m; i++) {
    		e[i].cnt += mp2[{e[i].a, e[i].b}];
    		e[i].cnt += mp2[{e[i].a, e[i].c}];
    		e[i].cnt += mp2[{e[i].b, e[i].c}];
    		if(e[i].cnt == 2)	Q.push(i);
    	}
    	while(!Q.empty()) {
    		int u = Q.front();
    		Q.pop();
    		q[++ans] = u;
    		vis[u] = 1;
    		pii pa;
    		if(!mp2[{e[u].a, e[u].b}])	pa = {e[u].a, e[u].b};
    		if(!mp2[{e[u].a, e[u].c}])	pa = {e[u].a, e[u].c};
    		if(!mp2[{e[u].b, e[u].c}])	pa = {e[u].b, e[u].c};
    		mp2[{pa.fi, pa.se}] = 1;
    		for(auto t : vv[mp[{pa.fi, pa.se}]]) {
    			e[t].cnt++;
    			if(e[t].cnt == 2)	Q.push(t);
    		}
    	}
    	if(n==3)	q[++ans] = 1;
    }
    
    int main() {
    	// freopen("in", "r", stdin);
    	scanf("%d", &T);
    	while(T--) {
    		scanf("%d", &n);
    		tol = 0, mp.clear(), mp2.clear();
    		for(int i=1; i<=n; i++)	g[i].clear(), vv[i].clear();
    		for(int i=1; i<=n; i++)	p[i] = q[i] = pos[i] = vis[i] = 0;
    		for(int i=1; i<=n-2; i++) {
    			int a, b, c;
    			scanf("%d%d%d", &a, &b, &c);
    			if(a>b)	swap(a, b);
    			if(a>c)	swap(a, c);
    			if(b>c)	swap(b, c);
    			g[a].pb(b), g[a].pb(c);
    			g[b].pb(a), g[b].pb(c);
    			g[c].pb(a), g[c].pb(b);
    			if(!mp.count({a, b}))	mp[{a, b}] = ++tol, vv[tol].clear();
    			if(!mp.count({a, c}))	mp[{a, c}] = ++tol, vv[tol].clear();
    			if(!mp.count({b, c}))	mp[{b, c}] = ++tol, vv[tol].clear();
    			vv[mp[{a, b}]].pb(i);
    			vv[mp[{a, c}]].pb(i);
    			vv[mp[{b, c}]].pb(i);
    			e[i] = {a, b, c, 0};
    		}
    		for(int i=1; i<=n; i++)	g[i].pb(n+1), sort(g[i].begin(), g[i].end());
    		pos[1] = p[1] = 1, m = n-2;
    		dfs(1);
    		topu();
    		for(int i=1; i<=n; i++)	printf("%d%c", p[i], i==n ? '
    ':' ');
    		for(int i=1; i<=m; i++)	printf("%d%c", q[i], i==m ? '
    ':' ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    CSS媒体查询
    重新认识caniuse
    范仁义css3课程---40、box-sizing属性实例
    前端超级实用技巧---2、css、js兼容性查询网站can i use
    日常英语---200221(shrink)
    心得体悟帖---200221(方针:进可攻退可守的方式:先把不熟悉的知识点录)
    心得体悟帖---200221(本来二月份就到了三月之期的)
    心得体悟帖---200220(对不同的人,用不同的处理方式(这个你远远没有理解))
    java中的String.format使用
    android中的ellipsize设置(省略号的问题)
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/12099360.html
Copyright © 2020-2023  润新知