1. 程式人生 > >2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) 部分題/平衡樹/最小環/思路bfs

2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) 部分題/平衡樹/最小環/思路bfs

交題地址

難度按照順序遞增

J - Judging Moose
隊友敲的

#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
   int l, r;
   while(~scanf("%d %d", &l, &r)){
    if(l == r && l != 0){
        printf("Even ");
    }
    else if(l != r && (l != 0 || r != 0)){
        printf
("Odd "); } else{ puts("Not a moose"); continue; } int mid = (l + r); if(l == mid / 2 && r == mid / 2){ printf("%d\n", mid); } else printf("%d\n",max(l, r) * 2); } }

B - Best Relay Team
隊友敲的

#include <iostream>
#include <cstdio>
#include <cstring> #include <algorithm> using namespace std; const int maxn = 500 + 10; const double inf = 1 << 30; int n; struct runer{ string name; double f; double s; }runers[maxn]; int cmp(runer a, runer b){ if(a.s - b.s < 0) return 1; else return 0; } int main() { //freopen("input.txt", "r", stdin);
while(scanf("%d", &n) != EOF){ for(int i = 0; i < n; i++){ cin >> runers[i].name; scanf("%lf%lf", &runers[i].f, &runers[i].s); } sort(runers + 0, runers + n, cmp); // for(int i = 0; i < n; i++){ // cout << runers[i].name <<" "<<runers[i].f <<" "<< runers[i].s<< endl ; //// scanf("%lf%lf", &runers[i].f, &runers[i].s); // } double minimum = inf; int res[5], cnt; for(int i = 0; i < n; i++){ double temp = 0; int tmplist[5]; cnt = 0; temp += runers[i].f; tmplist[cnt++] = i; for(int j = 0; j < n; j++){ if(i != j){ temp += runers[j].s; tmplist[cnt++] = j; if(cnt == 4) break; } } //cout << "%" << i <<" "<< temp <<endl; if(temp - minimum < 0){ minimum = temp; for(int j = 0; j < 4; j++) res[j] = tmplist[j]; } } printf("%.2lf\n",minimum); for(int i = 0; i < 4; i++){ //cout <<runers[res[i]].f << " "<< runers[res[i]].s<< " "; cout << runers[res[i]].name << endl; } } return 0; }

I - Import Spaghetti
在題目所給的有向圖中找一個最小的環,並按照環的順序逆向輸出(任意起點皆可)
每個點bfs。。。居然在很智障的地方寫re了(因為輸入陣列開小了哈哈哈)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
using namespace std;
const int maxn = 610;
const int inf = 0x3f3f3f3f;
vector<int> mp[maxn];
map<string,int> change;
char in[100010];
bool vis[maxn];
int num[maxn],res,n;
int pre[510],dis[510];
bool bfs(int root){
    memset(dis, inf, sizeof(dis));
    bool flag = true;
    queue<int> que;
    que.push(root);
    while(!que.empty()){
        int q = que.front();
        if(q==root){
            if(!flag){
                res = dis[root];
                return true;
            }else{
                flag = false;
            }
        }
        que.pop();
        for(int i=0;i<mp[q].size();i++){
            int now;
            if(q==root){
                now = 1;
            }else{
                now = dis[q] + 1;
            }
            if(dis[mp[q][i]] > now){
                que.push(mp[q][i]);
                dis[mp[q][i]] = now;
            }
        }
    }
    return false;
}
int main(){
    string name[maxn];
    //freopen("29-496.4.in", "r", stdin);
    int i,j,a,k,killme;
    string str,now;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        cin>>name[i];
        change[name[i]] = i;
    }
    for(i=1;i<=n;i++){
        cin>>str>>a;
        int to = change[str];
        for(j=1;j<=a;j++){
            cin>>str;
            getchar();
            gets(in);
            int p1 = 0;
            int len = strlen(in);
            for(k=0;k<len;k++){
                if(in[k] == ','){
                    in[k] = '\0';
                    now = in + p1;
                    mp[change[now]].push_back(to);
                    k += 2;
                    p1 = k;
                    continue;
                }
            }
            now = in + p1;
            mp[change[now]].push_back(to);
        }
    }
    res = inf;
    int pos = -1, maxx = inf;
    for(i=1;i<=n;i++){
        memset(vis, false, sizeof(vis));
        bool flag = bfs(i);
        if(res < maxx && flag){
            maxx = res;
            pos = i;
        }
    }
    if(res == inf){
        cout<<"SHIP IT\n";
        return 0;
    }
    queue<int> que;
    que.push(pos);
    memset(dis, inf, sizeof(dis));
    while(!que.empty()){
        int q = que.front();
        que.pop();
        for(i=0;i<mp[q].size();i++){
            int now;
            if(q == pos){
                now = 1;
            }else{
                now = dis[q] + 1;
            }
            if(dis[mp[q][i]] > now){
                pre[mp[q][i]] = q;
                que.push(mp[q][i]);
                dis[mp[q][i]] = now;
            }
            if(mp[q][i] == pos){
                pre[pos] = q;
                goto here;
            }
        }
    }
here:
    int x = pos, p =0;
    while(pre[x] != pos){
        cout<<name[pre[x]]<<" ";
        x = pre[x];
    }
    cout<<name[pos];

    return 0;
}

G - Galactic Collegiate Programming Contest
比賽時想會不會是平衡樹,但是並不會寫
套了wenwenla的平衡樹板子一下就過了
附上wenwenla板子 github地址:https://github.com/wenwenla/ACM

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cassert>
using namespace std;
const int maxn = 1e5+10;
struct unit{
    int prom, time;

    bool operator==(unit rhs) const {
        return prom == rhs.prom && time == rhs.time;
    }
}save[maxn];
bool compare(unit a,unit b){
    if(a.prom == b.prom){
        return a.time < b.time;
    }else{
        return a.prom > b.prom;
    }
}
template<typename T, class _Comp = less<T>>
struct Treap {
    const static int NODECNT = maxn;
    struct Node {
        int ch[2], p, sz;
        T v;
        void make(int _l, int _r, int _p, const T& _v) {
            ch[0] = _l; ch[1] = _r; p = _p; v = _v; sz = 1;
        }
    } node[NODECNT];
    int m_rt, mp[NODECNT], mp_idx, node_idx;

    void maintain(int x) {
        node[x].sz = 1;
        node[x].sz += node[x].ch[0] == -1 ? 0 : node[node[x].ch[0]].sz;
        node[x].sz += node[x].ch[1] == -1 ? 0 : node[node[x].ch[1]].sz;
    }
    _Comp cmp;

    explicit Treap(const _Comp& c) : cmp(c) { unsigned seed = 19971023; srand(seed); clear(); }

    Treap() : cmp(_Comp()) { unsigned seed = 19971023; srand(seed); clear(); }

    void clear() { m_rt = -1; mp_idx = -1; node_idx = 0; }

    void ins(const T& val) { _ins(m_rt, val); }
    void _ins(int& rt, const T& val) {
        if(rt == -1) {
            if(mp_idx == -1) { node[rt = node_idx++].make(-1, -1, rand(), val); }
            else { node[rt = mp[mp_idx--]].make(-1, -1, rand(), val); }
        } else {
            int type = cmp(node[rt].v, val);
            _ins(node[rt].ch[type], val);
            maintain(rt);
            if(node[rt].p < node[node[rt].ch[type]].p) rotate(rt, type);
        }
    }

    void del(const T& val) { _del(m_rt, val); }
    void _del(int& rt, const T& val) {
        assert(rt != -1);
        if(node[rt].v == val) {
            if(node[rt].ch[0] == -1) {
                mp[++mp_idx] = rt;
                rt = node[rt].ch[1];
            } else if(node[rt].ch[1] == -1) {
                mp[++mp_idx] = rt;
                rt = node[rt].ch[0];
            } else {
                int next = node[node[rt].ch[0]].p < node[node[rt].ch[1]].p;
                rotate(rt, next);
                _del(node[rt].ch[next ^ 1], val);
                maintain(rt);
            }
        } else {
            _del(node[rt].ch[cmp(node[rt].v, val)], val);
            maintain(rt);
        }
    }

    int find(const T& val) {
        int rt = m_rt;
        while(rt != -1) {
            if(node[rt].v == val) return rt;
            rt = node[rt].ch[cmp(node[rt].v, val)];
        }
        return -1;
    }

    void rotate(int& rt, int type) {
        int tmp = node[rt].ch[type];
        node[rt].ch[type] = node[tmp].ch[type ^ 1];
        node[tmp].ch[type ^ 1] = rt;
        maintain(rt); maintain(tmp);
        rt = tmp;
    }

    int kth(int k) {
        assert(k >= 1 && k <= size());
        int rt = m_rt, res = -1;
        while(rt != -1) {
            int le = node[rt].ch[0] == -1 ? 0 : node[node[rt].ch[0]].sz;
            if(le == k - 1) {
                res = node[rt].v;
                break;
            } else if(le > k - 1) {
                rt = node[rt].ch[0];
            } else {
                k -= le + 1;
                rt = node[rt].ch[1];
            }
        }
        return res;
    }

    int rank(const T& val) {
        int rt = m_rt, cnt = 0;
        while(rt != -1) {
            int le = node[rt].ch[0] == -1 ? 0 : node[node[rt].ch[0]].sz;
            if(cmp(node[rt].v, val)) {
                cnt += le + 1;
                rt = node[rt].ch[1];
            } else {
                rt = node[rt].ch[0];
            }
        }
        return cnt + 1;
    }

    int size() { return node[m_rt].sz; }
};
Treap<unit, bool(*)(unit, unit)> tr (compare);
int main(){
    tr.clear();
    int n,m,i,j,a,b;
    while(~scanf("%d%d",&n,&m)){
        for(i=1;i<=n;i++){
            save[i].prom = 0;
            save[i].time = 0;
            tr.ins(save[i]);
        }
        for(i=1;i<=m;i++){
            scanf("%d%d",&a, &b);
            tr.del(save[a]);
            ++save[a].prom;
            save[a].time += b;
            tr.ins(save[a]);
            printf("%d\n",tr.rank(save[1]));
        }
    }

    return 0;
}

D - Distinctive Character

先講一下設定,對於兩個只含有0、1的串,它們的每一位如果相同則它們相似度+1
題目會給我們很多(1e5)這樣的串,然後讓我們給出一個01串,使得我們給出的串和題目輸入的所有串的相似度最大值最小
炒雞繞的,首先建圖(最大1e6個點),把每個題目輸入的串都當作起點,它們的相鄰點是僅有一個位置和自身位置不同的串。bfs一遍,這些源串起點能到達的最遠點即是問題所求。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 1e5+10;
const int inf = 0x3f3f3f3f;
char in[maxn];
int save[maxn];
queue<int> que;
int dis[(1<<20)+10];
int main(){
    int n,k,i,j;
    while (~scanf("%d%d",&n,&k)) {
        memset(save, 0, sizeof(save));
        memset(dis, inf, sizeof(dis));
        for(i=1;i<=n;i++){
            scanf("%s",in);
            for(j=0;j<k;j++){
                if(in[j]-'0'){
                    save[i] += (1<<j);
                }
            }
            dis[save[i]] = 0;
            que.push(save[i]);
        }
        int farthest = -1,res = 0;
        while(!que.empty()){
            int q = que.front();
            que.pop();
            for(i=0;i<k;i++){
                int nnext = q ^ (1<<i);
                if(dis[nnext] > dis[q]+1){
                    dis[nnext] = dis[q]+1;
                    que.push(nnext);
                    if(dis[nnext]>farthest){
                        res = nnext;
                        farthest = dis[nnext];
                    }
                }
            }
        }
        for(i=0;i<k;i++){
            if(res&(1<<i)){
                printf("1");
            }else{
                printf("0");
            }
        }
        printf("\n");
    }
    return 0;
}

相關推薦

2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017)(solve7/11)

B題 題意:給你n個人的第一棒的速度和其他棒的速度,然後讓你輸出最快的那個組合,輸出時間和人。 思想:模擬 D題 題意:給你n個01串代表每個人的特徵,現在讓你求一個和他們長度相等但是和他們相似度最對的那個串。 思想:考慮最短路問題,將每個串拆出來k個差一位的子

2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) 部分平衡思路bfs

交題地址 難度按照順序遞增 J - Judging Moose 隊友敲的 #include <iostream> #include <cstdio> using namespace std; int main() {

2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) A. Altruistic Amphibians DP

題目連結:https://codeforc.es/gym/101933/problem/A 題意:有 n 只青蛙在一個坑裡面,要求可以跳出坑的青蛙的最大數量。每個青蛙有 3 種屬性:l 為青蛙一次可以跳的高度,w 為青蛙的重量,h 為青蛙作為墊背時的高度,墊背的前提是墊背的青蛙的重量比在他上面的青蛙的總重量

2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) D. Delivery Delays 二分+短路+DP

題目連結:https://codeforc.es/gym/101933/problem/D 題意:地圖上有 n 個位置和 m 條邊,每條邊連線 u、v 且有一個距離 w,一共有 k 個詢問,每個詢問表示 ti 時間在位置 ui 有人下單點了披薩,而披薩店在 di 時間做好披薩可以送出去,披薩店在位置 1,送

2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

傳送門 A.Altruistic Amphibians     一個挺有意思的題目。首先考慮這樣的問題:倘若要讓儘可能多的青蛙能夠逃跑,則顯然羅漢最好疊得儘可能的高(這才能使得那些不能一次性跳出的青蛙能夠逃離)。     而顯然,對於那些體重最

(寒假GYM開黑)2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

put def operator money node tin 自己人 n) n-1 layout: post title: 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) auth

2015-2016 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2015) Goblin Garden Guards (數論)

題目大意:在第一象限記憶體在著n個黑點,然後同時存在著圓,求出不在圓內的個數 解題思路:本來這道題在資料很小的時候可以暴力去判,但是發現這個資料太大,所以需要進行優化和處理,我們列舉每個圓,找出這個

The 2018 ACM-ICPC Chinese Collegiate Programming Contest Take Your Seat

scanf com 分享圖片 pro name string 技術 證明 double /* 證明過程如下 :第一種情況:按1到n的順序上飛機,1會隨意選一個,剩下的上去時若與自己序號相同的座位空就坐下去,若被占了就也會隨意選一個。求最後一個人坐在應坐位置的概率 *

A - Multiplication Dilemma (思維)( 2018 ACM ICPC Arabella Collegiate Programming Contest

滴答滴答---題目連結  Multiplication operation is not always easy! For example, it is hard to calculate 27 × 20 using your mind, but it is eas

Multiplication Dilemma (思維)( 2018 ACM ICPC Arabella Collegiate Programming Contest

Multiplication operation is not always easy! For example, it is hard to calculate 27 × 20 using your mind, but it is easier to find the

2018 ACM-ICPC, Syrian Collegiate Programming Contest F - Pretests SOS dp

#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define

(寒假開黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽

ogr sign n) you end max ext %d col layout: post title: (寒假開黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽題) author: "l

2017-2018 ACM-ICPC Nordic ——Problem G 。Galactic Collegiate Programming Contest

Time limit: 6  secondsPicture by GuillaumePreat on Pixabay, cc0One hundred years from now, in 2117, the InternationalCollegiate Programmi

D. Dog Show 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred)

cto long space 。。 urn ext team south cpc http://codeforces.com/contest/847/problem/D 巧妙的貪心 仔細琢磨。。。 像凸包裏的處理 1 #include <cstdio>

Gym - 101615J Grid Coloring DP 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)

bitset typedef src order esp red memset return sizeof 題目傳送門 題目大意: 給出n*m的網格,有紅藍兩種顏色,每個格子都必須被染色,當一個格子被染成藍色後,這個格子左上方的一塊都必須被染成藍色,問最後的方案數量。 思路

2017-2018 ACM-ICPC, NEERC, Moscow Subregional Contest B - Byteland Trip dp

B - Byteland Trip 題目大意:給你一個由'<' 和 '>'組成的串, 如果在'<' 只能前往編號比它小的任意點, 反之只能前往比它大的任意點,問你能遍歷所有點 並且每個點只走一次終點在各個位置的方案數。 思路:感覺這種右能從左邊跑到右邊又跑回來的dp很難搞,如果我們確定

2017-2018 ACM-ICPC, Asia Daejeon Regional Contest 【11/12】

題目連結 A - Broadcast Stations 給出一棵樹,允許在某些點上新增權值,此時可以覆蓋距這個點不超過這個權值的所有點。求要覆蓋所有的點需要最少加的權值。 做的時候不會……韓語的題解機翻過來理解了好長時間OOOrz 讀了題多半就是樹形dp了。首先選取某個點作為根,然後

2017-2018 ACM-ICPC, NEERC, Moscow Subregional Contest

leak infinite odin clas rep nal history play com 地址 Rank Solved A B C D E F G H I J 51/298 6/10 O . O O . . O O O . O: 當場通過 ?:

Gym 101667I Slot Machines (2017-2018 ACM-ICPC, Asia Daejeon Regional Contest I)

傳送門:http://codeforces.com/gym/101667 Problem I Slot Machines Time Limit: 2 Seconds 題意:陣列a有n個數字,數字範圍0~999999希望求一組最小的k+p,使得任意i>k,都有a[i]=a[i+p],

2017-2018 ACM-ICPC, NEERC, Moscow Subregional Contest H - Hilarious Cooking [Gym/101611]

H - Hilarious Cooking [Gym/101611] 題面 思路 考慮序列中已經放置的最近的一組數 a ,