ICPC Asia Xuzhou 2019[網絡賽]——[ABEG]

問題蟲洞——A: Who is better?

 

黑洞內窺:

先求一組同餘方程(CRT),然後斐波那契博弈:

 

思維光年:

題目 == 題解

 

ACcode:

#include<stdio.h>
#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
#define MAXN 1000025
#define INF 0x3f3f3f3f//將近int類型最大數的一半,而且乘2不會爆int
#define MOD 1000000007 // MOD%4 = 3
const double pi = acos(-1.0);
const double eps = 1e-6;

ll b[MAXN], w[MAXN];		//w爲除數,b是餘數
ll exgcd(ll a, ll b, ll &x, ll &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int gcd = exgcd(b, a%b, x, y);
    int t = x;
    x = y;
    y = t - a/b*y;
    return gcd;
}

ll China(ll B[], ll W[], ll k) //W爲除數,B是餘數
{
    ll i, a, b, c, d, x, y, t;
    for(i=1; i<k; ++i)
    {
        a = W[i-1], b = W[i];
        c = B[i] - B[i-1];
        d = exgcd(a, b, x, y);
        if(c%d)
            return -1;
        t = b/d;
        x = (x*(c/d)%t+t)%t;
        B[i] = B[i-1] + W[i-1]*x;
        W[i] = W[i]/d*W[i-1];
    }
    return B[k-1];
}

ll f[75];
void init()
{
    f[1] = 1;
    f[2] = 2;
    for(int i=3; i<=73; ++i)
        f[i] = f[i-1] + f[i-2];
        //cout << f[73] << '\n';
}

int main()
{
    init();
    ll k, ans;
    scanf("%lld", &k);
    for(int i=0; i<k; ++i)
        scanf("%lld %lld", &w[i], &b[i]);

    ans = China(b, w, k);
    if(ans == -1) puts("Tankernb!");
    else
    {
        int flag = 0;
        for(int i=1; i<=73; ++i)
            if(ans == f[i])
            {
                flag = 1;
                break;
            }
        if(flag) puts("Lbnb!");
        else puts("Zgxnb!");
    }
    return 0;
}

 

問題蟲洞——B:so easy

 

黑洞內窺:

給你n個點m個操作,每次操作可以選擇1或2

1:刪除x

2:查詢x, 若x已被刪除,則輸出x+1,若x+1也被刪除,則繼續查找

 

思維光年:

我不知道爲什麼,我們隊也是用並查集查找,但就是T了,而且還是2001ms,,

後來,,,劃重點:

使用map.count()的查找查找複雜度會更低。。。。。

(老實說,用set暴力都可以過,我枯了~~~~~~~我隊wa了18發,鬼™知道換成count就過了,一看題解我們都sb了)

#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<string>
#include<map>
using namespace std;

map<int,int>q;
int n,m,t,x;

int tofind(int w)
{
    if(!q.count(w)) return w;
    return q[w] = tofind(q[w]);
}
int main()
{
    scanf("%d%d",&n,&m);
    while(m--)
    {
        scanf("%d%d",&t,&x);
        if(t == 1) q[x] = tofind(x + 1);
        if(t == 2) printf("%d\n",tofind(x));
    }
    return 0;
}

 

問題蟲洞——E:XKC's basketball team

 

黑洞內窺:

給出一個序列A,和一個值m,

求比第i個數ai+m還要大的數且這個數儘可能的靠右邊,設爲j, 若沒有則爲-1。

輸出n個數,每個數代表i與j之間的數.

 

思維光年:

棧維護+二分查找

(隊友嫌線段樹麻煩,,,然後就這樣被她A掉了。。。)

 

ACcde:

#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<string>
#include<map>
using namespace std;

const int maxn = 1e6 + 10;
int n,m,tot;
int a[maxn],b[maxn],c[maxn],ans[maxn];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n; ++i)
    {
        scanf("%d",&a[i]);
        ans[i] = -1;
    }
    tot = 0;
    for(int i = n;i >= 1; --i)
    {
        int p = lower_bound(c + 1,c + tot + 1,a[i] + m) - c;
        if(p <= tot) ans[i] = b[p] - i - 1;
        if(a[i] > c[tot]) b[++tot] = i,c[tot] = a[i];
    }
    for(int i = 1;i < n; ++i) printf("%d ",ans[i]);
    printf("-1\n");
    return 0;
}

 

問題蟲洞——G: Center

 

黑洞內窺:

給你一些點,你需要定一箇中心點,

使得你可以儘可能少的添加一些點,

使得添加這些點之後的點集中兩兩關於這個中心點對稱

 

思維光年:

一開始看到點數只有1000的時候就想着可能是暴力求解,

但是考慮到後面遍歷的點數敲不出來,,(還是自己太菜。。)

所以就沒有敲,後來發現是大水題。。。。

 

理性的思考:

有n個點,每個點都與其它所有的點(包括它自己)連線,求所有生成的中點,

然後我們從這些中點當中找出出現次數最多的那個就行,

設它的出現次數爲num,則答案就爲n-num。

 

ACcode:

//#include<bits/stdc++.h>
//std::ios::sync_with_stdio(false);
#include  <stdio.h>
#include <iostream>
#include<algorithm>
#include      <set>
#include      <map>
#include    <queue>
#include    <stack>
#include   <string>
#include   <math.h>
#include   <vector>
#include  <cstring>
#include <stdlib.h>
#include <string.h>
using namespace std;
typedef long long ll;
#define MAXN 1000005
#define INF 0x3f3f3f3f//將近ll類型最大數的一半,而且乘2不會爆ll
const ll mod = 998244353;
#define mem(a, b) memset(a, b, sizeof(a))

pair<int, int>point[1005];
map<pair<int, int>, int>mp;
int main()
{
    int n, ans = 0;
    cin >> n;
    for(int i=1; i<=n; ++i)
        scanf("%d %d", &point[i].first, &point[i].second);
    for(int i=1; i<=n; ++i)
    {
        for(int j=1; j<=n; ++j)
        {
            pair<int, int>p;            //*2是爲了防止小數
            p.first = (point[i].first*2+point[j].first*2)/2;
            p.second = (point[i].second*2+point[j].second*2)/2;
            mp[p]++;
            if(mp[p] > ans) ans=mp[p];
        }
    }
    cout << n-ans << '\n';
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章