8VC Venture Cup 2017 - Elimination Round

传送门:http://codeforces.com/contest/755

A题题意是给你一个数字n,让你找到一个数字m,使得n*m+1为合数,范围比较小,直接线性筛出1e6的质数,然后暴力枚举一下就好了。

#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 INF = 0x3f3f3f3f;
bool prim[maxn];
int main()
{
    int n;
    int m = sqrt(maxn + 0.5);
    for (int i = 2; i <= m; i++)
        if (!prim[i])
            for (int j = i * i; j < maxn; j += i)
                prim[j] = 1;
    prim[0] = prim[1] = 1;
    scanf("%d", &n);
    for (int i = 1; i <= 1000; i++)
        if (prim[i*n+1])
        {
            printf("%d\n", i);
            return 0;
        }
    return 0;
}
View Code

B题题意是A和B玩游戏,A有n个单词,B有m个单词,每个人轮流说一句单词,但是不能说重复的单词,说到最后没得说的人输,A先说,问最后A是否能赢。比较简单的贪心,找出两个人单词中的相同数量,这一部分是必须先讲的,可以处理出AB可以讲的单词数,比较一下大小就可以了。

#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;
set <string> s;
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    string str;
    int same = 0;
    for (int i = 0; i < n; i++)
    {
        cin >> str;
        s.insert(str);
    }
    for (int i = 0; i < m; i++)
    {
        cin >> str;
        if (s.count(str))
            same++;
    }
    int num1 = n - same + (same - same / 2);
    int num2 = m - same + same / 2;
    if (num1 > num2) puts("YES");
    else puts("NO");
    return 0;
}
View Code

C题题意没看懂。。直接看提示大概是给你n个节点,第i个节点和第a[i]个节点在同一棵树上,问有多少棵树。直接并查集或dfs处理出联通块的数量就行了。

#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 f[maxn];
int find(int x)
{
    return f[x] == x ? x : f[x] = find(f[x]);
}
int mix(int x, int y)
{
    int fx = find(x), fy = find(y);
    if (fx == fy) return 0;
    f[fx] = fy;
    return 1;
}
int main()
{
    int n, x;
    scanf("%d", &n);
    int sum = n;
    for (int i = 1; i <= n; i++) f[i] = i;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &x);
        if(mix(i, x)) sum--;
    }
    printf("%d\n", sum);
    return 0;
}
View Code

D题是给你n边形,然后每次相隔k个点连上一条边,问每次连边后该n边形一共有多少个面。可以考虑,每连一条边,多出的面数是两点直接线段的数量,所以直接树状数组/线段树统计下走过的点,每次增加的时候直接查询他们之间有多少个点就行了。注意要long long,还有要k=min(k,n-k);不然会多算。

#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 INF = 0x3f3f3f3f;
ll c[maxn];
int n;
int lowbit(int x)
{
    return x & (-x);
}
ll getsum(int x)
{
    ll ans = 0;
    while (x > 0)
    {
        ans += c[x];
        x -= lowbit(x);
    }
    return ans;
}
void updata(int x)
{
    while (x <= n)
    {
        c[x]++;
        x += lowbit(x);
    }
}
int main()
{
    int k;
    scanf("%d%d", &n, &k);
    k = min(n - k, k);
    ll add = 1, ans = 1, cur = 1;
    for (int i = 0; i < n; i++)
    {
        updata(cur);
        if (cur + k <= n) add = getsum(cur + k) - getsum(cur) + 1;
        else add = getsum(n) - getsum(cur) + getsum((cur + k - 1) % n + 1) + 1;
        ans += add;
        if (i == n - 1) cout << ans - 1;
        else cout << ans << " ";
        cur = (cur + k - 1) % n + 1;
        updata(cur);
//        for (int i=1;i<=n;i++)
//        cout<<getsum(i)-getsum(i-1)<<" ";
//        cout<<endl;
    }
    return 0;
}
View Code

这题也可以找规律做。。

#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 INF = 0x3f3f3f3f;
int main()
{
    ll n, k;
    cin >> n >> k;
    k = min(k, n - k);
    ll c = 1, add = 1, ans = 1;
    for (ll i = 1; i <= n; i++)
    {
        c += k;
        if (c > n)
        {
            add++;
            ans += add;
            add++;
            c %= n;
        }
        else ans += add;
        if (i == n) cout << ans - 1 << " ";
        else cout << ans << " ";
    }
    return 0;
}
View Code

总结:这次前面的题比较水,虽然是摸黑打的,手速慢了点,好在D没fst掉,升了171分,直接蓝名了,不枉熬夜到4点。可惜没把房间里十几个D题hack掉,终测完发现自己变成房间第一。总之再接再厉。

2017-01-16 15:34:14

posted @ 2017-01-16 15:35  酱油党gsh  阅读(255)  评论(0编辑  收藏  举报