zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 157 题解报告

    A:Duplex Printing

    题目大意 :

    给你一个数,一次能打印两面,问表示需要打印多少张才能将所有打印完。
    

    析题得侃 :

    如果这个数是偶数, 需要打印 n / 2
    如果这个数是奇数, 需要打印 n / 2 + 1.
    

    考察点:

    签到,思维
    

    Code:

    #include <map>
    #include <set>
    #include <queue>
    #include <deque>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define x first
    #define y second
    
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    typedef long long LL;
    typedef pair<int,int>PII; 
    
    int main(void) {
    	int n;
    	cin >> n;
    	if(n & 1) cout << n / 2 + 1 << endl;
    	else cout << n / 2 << endl;
    	return 0;
    }
    

    B:Bingo

    题目大意:

    给一个 3 * 3 的矩阵,每个位置有一个数,之后再给你一些数,如果这些数在这个矩阵中
    并且所以数组合到一起可以使得 有一列或者有一行或者斜对角 都出现过,就输出 Yes,
    否则输出 No.
    

    析题得侃:

    没有想到好的方法,就一个一个枚举了,hh,方法虽然笨点,总归是 AC 了。
    

    考察点 :

    模拟
    

    Code :

    #include <map>
    #include <set>
    #include <queue>
    #include <deque>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define x first
    #define y second
    
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    typedef long long LL;
    typedef pair<int,int>PII; 
    
    int a[5][5];
    int cnt[5][5];
    
    int main(void) {
    	for(int i = 1; i <= 3; i ++) {
    		for(int j = 1; j <= 3; j ++) {
    			cin >> a[i][j];
    		}
    	}
    	int n,value;
    	cin >> n;
    	while(n --) {
    		cin >> value;
    		bool vis = false;
    		for(int i = 1; i <= 3; i ++) {
    			for(int j = 1; j <= 3; j ++) {
    				if(a[i][j] == value) {
    					vis = true;
    					cnt[i][j] = 1;
    					break;
    				}
    			}
    			if(vis) break;
    		}
    	}
    	if((cnt[1][1] == 1 && cnt[1][2] == 1 && cnt[1][3] == 1) || (cnt[2][1] == 1 && cnt[2][2] == 1 && cnt[2][3] == 1) ||
    		(cnt[3][1] == 1 && cnt[3][2] == 1 && cnt[3][3] == 1) || (cnt[1][1] == 1 && cnt[2][1] == 1 && cnt[3][1] == 1) ||
    		(cnt[1][2] == 1 && cnt[2][2] == 1 && cnt[3][2] == 1) || (cnt[1][3] == 1 && cnt[2][3] == 1 && cnt[3][3] == 1) ||
    		(cnt[1][1] == 1 && cnt[2][2] == 1 && cnt[3][3] == 1) || (cnt[1][3] == 1 && cnt[2][2] == 1 && cnt[1][3] == 1)
    	) {
    		cout << "Yes" << endl;
    	} else {
    		cout << "No" << endl;
    	}
    	return 0;
    }
    

    C:Guess The Number

    题目大意:

    大概就是说给你一个不超过三位的一个数,然后这之后会有一些操作,可以指定某一位是多少,
    但是不允许有前导 0 ,同一个位置不能重复指定,否则会出现错误,除了指定的数外,还要保证
    最后得到的数是最小的。
    

    析题得侃:

    题是不难,就是细节忒多,需要考虑的情况比较多,这道题我还犯了一个小错误,就是重复输出了,
    对于某一种情况没有及时跳出来,导致对某一个测试样例会输出两个答案。不过这道题收获还是
    蛮多的,重要的是学会尝试着去找不同的情况去接近答案。
    

    考察点:

    思维,模拟
    

    Code:

    #include <map>
    #include <set>
    #include <queue>
    #include <deque>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define x first
    #define y second
    
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    typedef long long LL;
    typedef pair<int,int>PII;
    
    int n,m;
    
    int x,b;
    
    int a[4],cnt[4];
    
    int main(void) {
    	cin >> n >> m;
    	if(n == 1 && m == 0) {
    		// 这种情况要及时跳出来,不然就与下面的冲突了 
    		cout << 0 << endl;
    		return 0;
    	}
    	bool vis = true;
    	while(m --) {
    		cin >> x >> b;
    		if(vis == false) continue;
    		if(n > 1 && x == 1 && b == 0) {
    			vis = false;
    		} else if(cnt[x] && a[x] != b) {
    			vis = false;
    		} else {
    			a[x] = b;
    			cnt[x] = 1;
    		}
    	}
    	if(vis == false) {
    		cout << -1 << endl;
    	} else {
    		for(int i = 1; i <= n; i ++) {
    			if(a[1] == 0 && cnt[1] == 0) a[1] = 1;
    			cout << a[i] ;
    		}
    		cout << endl;
    	}
    	return 0;
    }
    

    D:Friend Suggestions

    题目大意:

    先给一些关系,表明两个数之间是朋友的关系,接着再给一些关系,表示这些人之间不是朋友的
    关系,最后问你每个人可以有多少个人可以是自己的候选朋友(不包括已有的),而且所有人跟
    自己还必须是在同一个连通块内的。
    

    析题得侃:

    这题是赛后补的,琢磨完第三题剩下的时间就不多了,跟一些大佬真的没法比,不过最后靠自己
    的能力把这道题补出来,自己还是很欣慰的。
    一看到这道题涉及到关系,第一时间想到的就是并查集,然后就往哪里想,实际上是带权并查集
    的初级版,我们最后求得是候选的朋友,我们可以求出这个连通块的大小,然后每个人的朋友就是
    当前这个点的出度,还有在同一个连通块中跟这个人也有可能不是朋友,这是我们可以拿一个
    cnt 数组用来计算不是朋友的数量(是双向的,具体的会在代码中体现),然后这个连通块的大小
    - 朋友数量 - 不是朋友的数量 = 候选朋友的数量(同一个连通块内)。
    

    考察点:

    带权并查集,连通块
    

    Code:

    #include <map>
    #include <set>
    #include <queue>
    #include <deque>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define x first
    #define y second
    
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    typedef long long LL;
    typedef pair<int,int>PII;
    
    const int maxn = 1e5 + 10;
    
    int vis[maxn],cnt[maxn];
    int fa[maxn],sz[maxn],deg[maxn];
    
    int ans = 0;
    
    int get(int x) {
    	return x == fa[x] ? x : fa[x] = get(fa[x]);
    }
    
    void Union(int x,int y) {
    	int xx = get(x);
    	int yy = get(y);
    	if(xx == yy) return ;
    	fa[yy] = xx;
    	sz[xx] += sz[yy];
    	return ;
    }
    
    int main(void) {
    	int n,m,k;
    	int u,v;
    	cin >> n >> m >> k;
    	for(int i = 1; i <= n; i ++) {
    		fa[i] = i;
    		// 刚开始每个都是独立的,都是一个 
    		sz[i] = 1;
    
    	}
    	for(int i = 1; i <= m; i ++) {
    		cin >> u >> v;
    		// 记录每个点的出度 
    		deg[u] ++;
    		deg[v] ++;
    		Union(u,v);
    	}
    	for(int i = 1; i <= k; i ++) {
    		cin >> u >> v;
    		if(get(u) == get(v)) {
    			// 不是朋友,但在同一个连通块内,所以都需要减少 
    			cnt[u] --;
    			cnt[v] --;
    		}
    	}
    	for(int i = 1; i <= n; i ++) {
    		cout << sz[get(i)] - deg[i] + cnt[i] - 1<< " ";
    	}
    	return 0;
    }
    

    E:Simple String Queries

    题目大意:

    有一串字符,我们可以执行两种操作:
    1、替换某个位置的字符
    2、查询某一段区间不同字符的个数
    

    析题得侃:

    很明显:这道题的两种操作分别是:单点修改,区间查询
    是不是跟树状数组的基本操作十分的类似,当然,线段树也是可以的,但是杀鸡焉用牛刀,
    关键是自己太菜,哈哈。我们可以用一个二维的数组记录当前位置之前每个字符出现的数量。
    具体实现看代码。
    

    考察点:

    树状数组,线段树
    

    Code:

    #include <cstdio> 
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 5e5 + 10;
    
    char a[maxn];
    
    int c[maxn][26];
    
    int t,op,pos,l,r,len;
    char v;
    
    int lowbit(int x) {
    	return x & -x;
    }
    
    void insert(int id,int x,int v) {
    	for(int i = id; i <= len; i += lowbit(i)) {
    		c[i][x] += v;
    	}
    	return ;
    }
    
    int query(int id,int x) {
    	int ans = 0;
    	// x 代表是( x - 'a') 
    	for(int i = id; i; i -= lowbit(i)) {
    		ans += c[i][x];
    	}
    	return ans;
    }
    
    int main(void) {
    	cin >> len;
    	scanf("%s",a + 1);
    	for(int i = 1; i <= len; i ++) {
    		int v = a[i] - 'a';
    		insert(i,v,1);
    	}
    	cin >> t;
    	while(t --) {
    		cin >> op; 
    		if(op == 1) {
    			cin >> pos >> v;
    			// 更新 
    			insert(pos,a[pos] - 'a',-1);
    			insert(pos,v - 'a',1);
    			a[pos] = v;                    // 修改后记得修改原数组 
    		} else {
    			cin >> l >> r;
    			int res = 0;
    			for(int i = 0; i < 26; i ++) {
    				// 如果这个区间有这个字符,只需要 + 一次即可 
    				if(query(r,i) - query(l - 1,i)) res ++;
    			}
    			cout << res << endl;
    		}
    	}
    	return 0;
    }
    

    F:Yakiniku Optimization Problem

    待补
    

    后记:

    本人能力有限,写的不当之处还望各位看官多多指教,如在参考中遇到各种问题,欢迎大家
    留言交流,共同交流。
  • 相关阅读:
    光纤网卡与HBA卡区别
    Windows远程桌面相关
    port bridge enable命令导致的环路
    堡垒机jumpserver测试记录--使用
    堡垒机jumpserver测试记录--安装
    Centos6.5升级openssh、OpenSSL和wget
    linux抓包工具tcpdump使用总结
    iOS -视频缩略图的制作
    Mac 上视图的坐标系统原点位于左下角
    Mac
  • 原文地址:https://www.cnblogs.com/prjruckyone/p/12398635.html
Copyright © 2011-2022 走看看