zoukankan      html  css  js  c++  java
  • Codeforces Round #297 (Div. 2)

    A. Vitaliy and Pie

    给你一个字符串,奇数位上是小写字母,偶数位上是大写字母,小写字母表示钥匙的类型能打开对应大写字母的门,

    大写字母表示门的种类,问之前还要买多少把钥匙,才能走完。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <set>
    using namespace std;
    #define INF 1000000000
    const int maxn = 1e5 + 10;
    char str[maxn * 2];
    int cnt[maxn * 2];
    int main()
    {
    	int n;
    	int ans = 0;
    	memset(cnt, 0, sizeof(cnt));
    	cin >> n;
    	cin >> str + 1;
    	for (int i = 1; i <= 2 * n - 2; i++){
    		if (i & 1){
    			int t = str[i] - 'a';
    			cnt[t]++;
    		}
    		else{
    			int t = str[i] - 'A';
    			if (cnt[t] == 0){
    				ans++; continue;
    			}
    			cnt[t]--;
    		}
    	}
    	cout << ans << endl;
    	return 0;
    }
    

      

    B. Pasha and String

    给出一个字符串,然后m个东西,每个东西一个数字a[i], 将 [a[i],|s| - a[i]+1] 的区间内的字符串倒置,输出最后的串的样子。

    因为是关于中点对称的,所以就记录每个点被覆盖的 次数,然后从左向中枚举,如果覆盖次数为奇数则交换a[i] ,a[s-i+1]。因为蠢了写了个线段树。。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <set>
    using namespace std;
    #define INF 1000000000
    
    #define  lson l,mid,rt<<1
    #define  rson mid+1,r,rt<<1|1
    const int maxn = 2 * 100000 + 10;
    char str[maxn];
    int color[maxn << 2];
    void build(int l, int r, int rt)
    {
    	color[rt] = 0;
    	if (l == r) return;
    	int mid = (l + r) >> 1;
    	build(lson); build(rson);
    }
    
    void down(int rt)
    {
    	if (color[rt]){
    		color[rt << 1] ^= 1; color[rt << 1 | 1] ^= 1;
    		color[rt] = 0;
    	}
    }
    void update(int L, int R, int l, int r, int rt)
    {
    	if (L <= l&&r <= R){
    		color[rt] ^= 1; return;
    	}
    	down(rt);
    	int mid = (l + r) >> 1;
    	if (L <= mid) update(L, R, lson);
    	if (R>mid) update(L, R, rson);
    }
    int ask(int key, int l, int r, int rt)
    {
    	if (l == r) return color[rt];
    	down(rt);
    	int mid = (l + r) >> 1;
    	if (key <= mid) return ask(key, lson);
    	else return ask(key, rson);
    }
    int main()
    {
    	int m, a;
    	scanf("%s", str + 1);
    	int len = strlen(str + 1);
    	cin >> m;
    	build(1, len, 1);
    	for (int i = 0; i<m; i++){
    		scanf("%d", &a);
    		update(a, len - a + 1, 1, len, 1);
    	}
    	for (int i = 1; i <= len / 2; i++){
    		int t = ask(i, 1, len, 1);
    		if (t) swap(str[i], str[len - i + 1]);
    	}
    	for (int i = 1; i <= len; i++)
    		printf("%c", str[i]);
    	cout << endl;
    	return 0;
    }
    

      

    C. Ilya and Sticks

    给出那么多根长度的火柴,每个火柴长度可以减1,也可以不减,四个火柴a,a,b,b类的可以拼成一个矩阵,问最后可以拼成的矩阵的和最大是多少?

    从高到低排序,然后贪心搞下就好了。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <set>
    using namespace std;
    typedef long long LL;
    LL cmp(const LL &a, const LL &b)
    {
    	return a>b;
    }
    const int maxn = 1e5 + 10;
    int a[maxn];
    int q[maxn];
    int main()
    {
    	int n;
    	cin >> n;
    	for (LL i = 1; i <= n; i++)
    		cin >> a[i];
    	sort(a + 1, a + n + 1, cmp);
    	LL ans = 0;
    	LL len = 0;
    	LL l, r;
    	for (LL i = 1; i<n; i++){
    		q[len++] = a[i];
    		if (a[i] == a[i + 1] || a[i] == a[i + 1] + 1){
    			q[len++] = a[i + 1]; i++; continue;
    		}
    		len--;
    	}
    	for (LL i = 0; i<len - 3; i += 4){
    		if (q[i] == q[i + 1]) l = q[i];
    		else l = q[i + 1];
    		if (q[i + 2] == q[i + 3]) r = q[i + 2];
    		else r = q[i + 3];
    		ans += l*r;
    	}
    	cout << ans << endl;
    	return 0;
    }
    

      

    D. Arthur and Walls

    给出一个n*m的图,*表示墙,.表示房间,问至少去了多少个*使得最后连通的房子中间没有墙这个东西,要求输出任意一副满足条件的图。

    把分成2*2的小方格,如果2*2的小方格李有一个*,那么这个*就要变成. 。最后使得不存在有2*2的小方格内只有一个*。比赛的时候没有想到,

    赛后还是没有想到,原本想的是把所有连通的最边界的四个顶点内的点全变为.。然后继续判,知道所有连通的图内不存在*为止。这个复杂度有点爆表。若是这个图合法,那么就不存在2*2的小方格里有一个*,分治搞,不好想,挺厉害的。为了省事,各种越界,a了。。无语。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <set>
    #include <stdlib.h>
    #include <cstdlib> 
    using namespace std;
    #define INF 1000000000
    int dx[] = { -1, -1, -1, 0, 1, 1, 1, 0 };
    int dy[] = { -1, 0, 1, 1, 1, 0, -1, -1 };
    const int maxn = 2222;
    char str[maxn][maxn];
    int vis[maxn][maxn];
    int judge(int x, int y)
    {
    	if (str[x][y] == '.') return 0;
    	if (str[x - 1][y - 1] == '.'&&str[x - 1][y] == '.'&&str[x][y - 1] == '.') return 1;
    	if (str[x - 1][y] == '.'&&str[x - 1][y + 1] == '.'&&str[x][y + 1] == '.') return 1;
    	if (str[x][y + 1] == '.'&&str[x + 1][y + 1] == '.'&&str[x + 1][y] == '.') return 1;
    	if (str[x + 1][y] == '.'&&str[x + 1][y - 1] == '.'&&str[x][y - 1] == '.') return 1;
    	return 0;
    }
    struct Node
    {
    	int x; int y;
    };
    
    queue<Node> q;
    int main()
    {
    	memset(vis, 0, sizeof(vis));
    	int n, m;
    	cin >> n >> m;
    	for (int i = 0; i < n; i++) scanf("%s", str[i]);
    	for (int i = 0; i < n; i++){
    		for (int j = 0; j < m; j++){
    			if (judge(i, j)){
    				Node t; t.x = i; t.y = j;
    				q.push(t);
    			}
    		}
    	}
    	while (!q.empty()){
    		Node  cur = q.front();
    		int x = cur.x; int y = cur.y; q.pop();
    		if (vis[x][y])continue;
    		vis[x][y] = 1;
    		//printf("%d %d
    ",x,y);
    		str[x][y] = '.';
    		for (int i = 0; i < 8; i++){
    			int xx = x + dx[i]; int yy = y + dy[i];
    			if (xx >= 0 && yy >= 0 && xx<n&&yy<m){
    				if (judge(xx, yy)){
    					Node k; k.x = xx; k.y = yy;
    					q.push(k);
    				}
    			}
    		}
    	}
    	for (int i = 0; i < n; i++){
    		for (int j = 0; j < m; j++) printf("%c", str[i][j]);
    		cout << endl;
    	}
    	return 0;
    }
    

      

    E. Anya and Cubes

    题意:n个数随便取,最多使得取得数里面的t个不超过k个变成其阶层的形式,使得最后和为s的方法数。

    比赛的时候随便写了个暴力,就睡了。

    此题用中途相遇法搞下,从中间折半,把左边搜到的值hash一下。在从右边搜,每次搜到一个S时,把hash表里值为 s - S且用的t不超过的k的的种类数相加.

    赛后用map水过,注意用map<int,int> m; 用m[5] 判断 ,和m.count(5) ;判断5这个键值存在不存在时候,是有时间差距的,m[5]直接访问如果不存在,则会插入一个0进去,这样会多了许多无用的值。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <set>
    using namespace std;
    #define INF 1000000000
    //typedef __int64 LL;
    typedef long long LL;
    int up;
    LL s;
    LL k, len1, len2;
    LL chart[100];
    map<int, LL> m[30];
    LL val;
    int a[100];
    LL jie(int x)
    {
    	LL ans = 1;
    	for (int i = 1; i <= x; i++) ans *= i;
    	return ans;
    }
    
    int gao(LL x)
    {
    	for (int i = 1; i <= 100; i++){
    		if (jie(i)>x){
    			return i - 1;
    		}
    	}
    }
    
    void init()
    {
    	for (int i = 1; i <= up; i++){
    		chart[i] = jie(i);
    	}
    }
    
    void dfs(int x, int ans, LL sum)
    {
    	if (x == len1 + 1){
    		//printf("%d %d
    ",k-ans,sum);
    		m[k - ans][sum]++; return;
    	}
    	dfs(x + 1, ans, sum);
    	if (sum + a[x] <= s) dfs(x + 1, ans, sum + a[x]);
    	if (a[x] <= up&&chart[a[x]] + sum <= s&&ans){
    		dfs(x + 1, ans - 1, sum + chart[a[x]]);
    	}
    }
    
    void DFS(int x, int ans, LL sum)
    {
    	if (x == len2 + 1){
    		//printf("%d %d
    ",k-ans,sum);
    		for (int i = 0; i <= ans; i++) if (m[i].count(s - sum)) val += m[i][s - sum];
    		return;
    	}
    	DFS(x + 1, ans, sum);
    	if (sum + a[x + len1] <= s) DFS(x + 1, ans, sum + a[x + len1]);
    	if (a[x + len1] <= up&&chart[a[x + len1]] + sum <= s&&ans){
    		DFS(x + 1, ans - 1, sum + chart[a[x + len1]]);
    	}
    }
    
    
    int main()
    {
    	int n;
    	val = 0;
    	cin >> n >> k >> s;
    	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    	up = gao(s); init();
    	len1 = n / 2; len2 = n - len1;
    	dfs(1, k, 0); DFS(1, k, 0);
    	cout << val << endl;
    	return 0;
    }
    

      

  • 相关阅读:
    Java 虚拟机部分面试题
    Java 多线程部分面试题
    Java IO部分面试题
    Java 集合框架部分面试题
    Java 面向对象面试题
    Java 多线程同步的五种方法
    Python操作redis
    Python操作mysql
    Python操作mongodb
    数据处理的全过程---(获取数据-清洗数据-数据建模-数据可视化)
  • 原文地址:https://www.cnblogs.com/yigexigua/p/4380060.html
Copyright © 2011-2022 走看看