Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined)

传送门: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\n", ans);
    return 0;
}
View Code

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\n", max(1, solve()));
    return 0;
}
View Code

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;
}
View Code

其他题暂时还不会,总结一下:本来以为这次混合场能够混点分,结果反而掉了八十多分,还是too naive。这场主要是没注意细节,以及题目根本看不懂= =。虽说对英语本来也不感冒,不过以后还是多看看英文题吧,少点用翻译了。END。

2017-01-13 23:42:34

posted @ 2017-01-13 23:43  酱油党gsh  阅读(133)  评论(0编辑  收藏  举报