传送门:http://codeforces.com/contest/757
A题题意是给你一个字符串,让你在里面找到"Bulbasaur"这样的单词有多少个,字符串可以重排列。实际上统计下"Bulbasaur"里面的字母数,再用原串的字母数去除一下取最小值就行了。可以直接两个map搞。这题被hack了一次是因为我错误地复制了case1,case1比原串多了个字母b。下次要仔细看清。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <string> #include <stack> #include <map> #include <set> #include <bitset> #define X first #define Y second #define clr(u,v); memset(u,v,sizeof(u)); #define in() freopen("data","r",stdin); #define out() freopen("ans","w",stdout); #define Clear(Q); while (!Q.empty()) Q.pop(); #define pb push_back using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5 + 10; const int INF = 0x3f3f3f3f; char str[maxn]; const char s[] = {"Bulbasaur"}; map<char, int> M, M2; int main() { scanf("%s", str); int len = strlen(str), lens = strlen(s), ans = INF; for (int i = 0; i < len; i++) { M[str[i]]++; } for (int i = 0; i < lens; i++) M2[s[i]]++; for (map<char, int>::iterator it = M2.begin(); it != M2.end(); it++) { ans = min(M[it->X] / it->Y, ans); } printf("%d ", ans); return 0; }
B题题意是给你一个集合,让你找到一个子集,这个子集里面的数字两两的gcd都不为1,求子集元素最多是多少。我的做法是把集合中的数字做下标记,然后用类似线性筛的做法,从素数开始枚举,更新这个素数的倍数被标记过的最大数量,也就是能够放在同一集合的最大数量。还有个坑点是,1要特判,如果有多个1,只能选择其中一个,因为gcd(1,1)==1。如果有多个大于1的数,可以选多个。比如2 2 2 输出 2,因为gcd(2,2)=2。这题还是比较容易想到的,不过我还是犯了细节错误,范围习惯性写出了sqrt(1e5),导致大于sqrt(1e5)的素数没有被枚举到。实在是太粗心了= =。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <string> #include <stack> #include <map> #include <set> #include <bitset> #define X first #define Y second #define clr(u,v); memset(u,v,sizeof(u)); #define in() freopen("data","r",stdin); #define out() freopen("ans","w",stdout); #define Clear(Q); while (!Q.empty()) Q.pop(); #define pb push_back using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5 + 10; const int INF = 0x3f3f3f3f; int Hash[maxn]; bool prime[maxn]; int solve() { int ans = 0; for (int i = 2; i < maxn; i++) { int temp = 0; if (!prime[i]) for (int j = i ; j < maxn; j += i) { if (Hash[j]) temp += Hash[j]; prime[j] = 1; } ans = max(ans, temp); } return ans; } int main() { int n, x; scanf("%d", &n); if (n == 1) { printf("1"); return 0; } for (int i = 0; i < n; i++) { scanf("%d", &x); Hash[x] ++; } printf("%d ", max(1, solve())); return 0; }
C题题意看了好久,最后还是看错了题意,导致无限wa6。题意是有n个道馆,m种精灵。每个道馆有gi只精灵,他们可以相互进化当他们在该道馆的数量相同,且在其他的道馆每个道馆里面的数量都要相同。(ps:全部道馆的两只精灵数量相同未必能进化,必须保证每个子道馆的精灵数量相同)。理解了题意后就很水了。开个vector V[maxn],V[i]表示第i只精灵在哪个道馆出现过,再对V数组排个序(这个cmp看起来有点像字典序的cmp),然后找到重复部分,A(n,n)算一下就行了。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <string> #include <stack> #include <map> #include <set> #include <bitset> #define X first #define Y second #define clr(u,v); memset(u,v,sizeof(u)); #define in() freopen("data","r",stdin); #define out() freopen("ans","w",stdout); #define Clear(Q); while (!Q.empty()) Q.pop(); #define pb push_back using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e6 + 10; const int maxm = 1e6 + 10; const int INF = 0x3f3f3f3f; const ll mod = 1e9 + 7; vector <int> G[maxn]; int main() { int n, m; ll ans = 1; scanf("%d%d", &n, &m); while (n--) { int g, x; scanf("%d", &g); while (g--) { scanf("%d", &x); G[x].pb(n); } } ll temp = 1; sort(G + 1, G + m + 1); // for (int i = 1; i <= m; i++) // { // for (int j = 0; j < G[i].size(); j++) // printf("%d ", G[i][j]); // puts(""); // } for (int i = 2; i <= m; i++) { if (G[i] == G[i-1]) { temp++; ans = (ans * temp) % mod; } else temp = 1; } cout << ans << endl; return 0; }
其他题暂时还不会,总结一下:本来以为这次混合场能够混点分,结果反而掉了八十多分,还是too naive。这场主要是没注意细节,以及题目根本看不懂= =。虽说对英语本来也不感冒,不过以后还是多看看英文题吧,少点用翻译了。END。
2017-01-13 23:42:34