首先庆祝一下再次血崩...
A - Bear and Big Brother 【数学】
题意:甲身高小于等于乙,甲每年身高翻两倍,乙翻一倍,求需要几年甲能比乙高。
做法:无fuck说
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#include <bits/stdc++.h> #define MEM(a,b) memset( a, b, sizeof(a) ) #define PII pair<int,int> const int INF = 0x3f3f3f3f; using namespace std; int main() { int a, b; cin >> a >> b; int sum = 0; while (a <= b) { a *= 3; b *= 2; sum ++; } cout << sum << endl; } |
B - Bear and Friendship Condition 【并查集】
题意:
给一个图:要求满足,A和B是朋友,B和C是朋友,那么A和C一定是朋友。
如下图(左边的满足,右边的不满足)
做法:
并查集求,对每个点判断是否满足完全图。
我WA在了:没有统计每个集合的元素,最终判断每个点的边数是否等于fa点的边数。
这样做没有考虑集合的所有点构成环的情况,如下图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#include <bits/stdc++.h> #define MEM(a,b) memset( a, b, sizeof(a) ) #define PII pair<int,int> const int INF = 0x3f3f3f3f; using namespace std; int fa[150150]; int sum[150150]; bool vis[150150]; int n, m; vector< int >mp[150150]; int find( int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); } int main() { int x, y; scanf ( "%d%d" , &n, &m); for ( int i = 1; i <= n; i++) fa[i] = i, sum[i] = 1; for ( int i = 1; i <= m; i++) { scanf ( "%d%d" , &x, &y); mp[x].push_back(y); //建立邻接矩阵,用来累计边的条数 mp[y].push_back(x); int xx = find(x); int yy = find(y); if (xx != yy) { fa[xx] = yy; sum[yy] += sum[xx]; //统计集合内有几个元素 } } MEM(vis, false ); for ( int i = 1; i <= n; i++) { int x = find(i); if (mp[i].size() != sum[x] - 1) { //假设集合有n个元素,那么每个元素都必须满足n-1条边 puts ( "NO" ); return 0; } } puts ( "YES" ); } |
C - Bear and Different Names 【模拟+贪心】
题意:
有n个人, 判断每k个人是否有同名,让你写出符合条件的任意人名
(人名由英文字母构成,第一个字母大写)
做法:
1.首先给YES的人编名字
2.给NO的人编名字,存在3种情况
a.[i,i+k-1]的范围内全部没取名字:给他们全部起同一个名字
b.[i,i+k-1]的范围内取了部分名字:给剩余没取名字的取任意一个区间内已经取好的名字
c.[i,i+k-1]的范围内全部已经取好名字:让最后一个人名改成第一个人的人名(贪心),
因为第i个人的人名并不影响下一波判断YES/NO的判断。
我就忘了考虑c情况所以WA了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#include <bits/stdc++.h> #define MEM(a,b) memset( a, b, sizeof(a) ) #define PII pair<int,int> using namespace std; int main() { int n, k; cin >> n >> k; string name[100]; //起名字2333 for ( int i = 0; i < 52; i++) name[i] = "A" ; for ( int i = 0; i < 26; i++) name[i] += ( 'a' +i); for ( int i = 26; i < 52; i++) name[i] += ( 'a' +i-26); for ( int i = 26; i < 52; i++) name[i] += ( 'a' +i-26); string vec[100]; for ( int i = 0; i < n-k+1; i++) cin >> vec[i]; string ans[100]; //最终结果 int idx = 0; bool vis[100]; MEM(vis, false ); for ( int i = 0; i < 100; i++) ans[i].clear(); //先给YES的排名字,记录是否取了名字 for ( int i = 0; i < n-k+1; i++) { if (vec[i] == "YES" ) { for ( int j = i; j <= i+k-1; j++) { if (vis[j]) continue ; ans[j] = name[idx++]; vis[j] = true ; } } } //给NO的人起名字,注意考虑3种情况 for ( int i = 0; i < n-k+1; i++) { if (vec[i] == "NO" ) { set<string>st; st.clear(); string temp = "" ; for ( int j = i; j <= i+k-1; j++) { if (vis[j]) { temp = ans[j]; break ; } } if (temp.size() == 0) { //情况A for ( int j = i; j <= i+k-1; j++) { ans[j] = name[idx]; vis[j] = true ; } idx++; } else { for ( int j = i; j <= i+k-1; j++) { //情况B if (vis[j] == false ) { ans[j] = temp; vis[j] = true ; } else { st.insert(ans[j]); //如果size等于k说明所有人都已经取了名字 } } if (st.size() == k) ans[i+k-1] = temp; //情况C } } } for ( int i = 0; i < n; i++) { if (i > 0) cout << ' ' ; cout << ans[i]; } cout << endl; } |