1. 程式人生 > >hihocoder [Offer收割]程式設計練習賽19

hihocoder [Offer收割]程式設計練習賽19

題目1 : 大禮堂地毯


列舉

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
char pattern[51][51];
char map[101][801];
int n, m,k;
int work(int h,int w){
    for(int i = 0;i < h; i++){
        for(int j = 0;j < w;j ++){
            if(map[i][j] != map[i%n][j%m])
                return 0;
        }
    }

    for(int i = 0;i < n; i++){
        for(int j = 0;j < m;j ++){
            int flag = 1;
            for(int l = 0; l < min(n,h) && flag; l++){
                for(int p = 0;p < min(m,w) && flag; p++){
                    if(map[l][p] != pattern[(l+i)%n][(p+j)%m])
                        flag = 0;
                }
            }
            if(flag) return 1;
        }
    }
    return 0;

}
int main(){
    cin>>n>>m>>k;
    for(int i = 0;i < n; i++)
        scanf("%s",pattern[i]);
    for(int j = 0;j < k; j++){
        int h,w;
        cin>>h>>w;
        for(int i = 0;i < h; i++){
            scanf("%s",map[i]);
        }
        if(work(h,w) == 1)printf("YES\n");
        else printf("NO\n");
    }
}

題目2 : 陣列重排3

從初始序列做bfs,然後給每個能到的序列標記步數。

如果目標序列被標記,輸出

否則不可達

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<map>
#include<queue>
using namespace std;
int n;
int num[10];
char input[10];
map<int,int> state;


int main(){
    int t,x;
    cin>>t;

    while(t--){
            getchar();
        scanf("%s",input);
        n = strlen(input);
        int need = 0;
        for(int i = 0;i < n; i++)
            need = need * 10 + input[i] - '0';

        state.clear();

        queue<int> Q;
        int u = 0;
        for(int i = 1;i <= n; i++){
            u =u * 10 + i;
        }
        int use[20],buf[20];
        Q.push(u);
        state[u] = 0;
        while(Q.size() > 0){
            u = Q.front();
            Q.pop();
            int p = u;
            for(int i = n;i > 0; i--){
                use[i] = u % 10;
                u /= 10;
            }

            for(int i = 1;i < n; i++){
                for(int j = 1;j < n; j++){
                    if(i == j) continue;
                    for(int k = 1;k <= n; k++){
                        if(k == i)
                            buf[j] = use[k];
                        else if(k == i + 1)
                            buf[j+1] = use[k];
                        else if(k >= min(i,j) && k <= max(i+1,j+1)){
                            if(j > i)
                                buf[k-2] = use[k];
                            else
                                buf[k+2] = use[k];
                        }
                        else buf[k] = use[k];
                    }
                    int v = 0;
                    for(int i = 1;i <= n; i++)
                        v = v * 10 + buf[i];
                    if(state.find(v) != state.end()) continue;
                    Q.push(v);
                    state[v] = state[p] + 1;
                }
            }

        }
        if(state.find(need) != state.end()) cout<<state[need]<<endl;
        else cout<<-1<<endl;


    }
    return 0;
}


題目4 : 相交的鐵路線

最近公共祖先。

lca求法寫的不好,複雜度是nlogn*logn的,實際可以少一個log

對於一條鐵路上兩個點的最近公共祖先F1,F2

F1,F2中深度較深的點,要麼是交點,要麼兩條鐵路沒有交點。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<map>
#include<queue>
#include<vector>
using namespace std;
int n;
#define maxn 100007
int rmq[20][100007];
vector<int>head[maxn];
int father[maxn],depth[maxn];
void dfs(int u,int f,int dep){
    if(father[u] != -1) return;
    father[u] = f;
    depth[u] = dep;
    for(int i = 0;i < head[u].size();i++){
        dfs(head[u][i],u,dep+1);
    }
}

void initRMQ(int n){
    for(int i = 1;i <= n; i++)
        rmq[0][i] = father[i];
    for(int i = 1;i <= 18;i ++){
        for(int j = 1;j <= n; j++){
            int u =rmq[i-1][j];
            rmq[i][j] = rmq[i-1][u];
        }
    }
//    for(int i = 0;i < 3; i++){
//        for(int j = 1;j <= n; j++)
//            cout<<rmq[i][j]<<" ";
//        cout<<endl;
//    }
}

int getDepFather(int id,int dep){
    dep = depth[id] - dep;
    if(dep == 0) return id;
    for(int i = 0; dep > 0; i++){
        int k = dep % 2;
        dep /= 2;
        if(k)
            id=rmq[i][id];
    }
    return id;
}
int getFather(int x1,int x2){
    int low = 1, high = min(depth[x1],depth[x2]);
    while(low <= high){
        int mid = (low + high) / 2;
//        cout<<x1<<" "<<mid<<" "<<getDepFather(x1,mid)<<endl;
//        cout<<x2<<" "<<mid<<" "<<getDepFather(x2,mid)<<endl;
        if(getDepFather(x1,mid) == getDepFather(x2,mid))
            low =  mid + 1;
        else
            high = mid - 1;
    }
    return getDepFather(x1,high);
}

int main(){
    int t,n,m,u,v,x1,x2,y1,y2;
    cin>>t;
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i = 0;i <= n; i++)
            head[i].clear();
        for(int i = 1;i < n; i++){
            scanf("%d%d",&u,&v);
            head[u].push_back(v);
            head[v].push_back(u);
        }
        memset(father,-1,sizeof(father));
        dfs(1,1,1);
        initRMQ(n);
        for(int i = 0;i < m; i++){
            scanf("%d%d%d%d",&x1,&x2,&y1,&y2);
            int f1 = getFather(x1,x2);
            int f2 = getFather(y1,y2);

            if(depth[f1] < depth[f2])
                f1 = f2;
            f1 = depth[f1];
            int t1 = getDepFather(x1,f1);
            int t2 = getDepFather(x2,f1);
            int z1 = getDepFather(y1,f1);
            int z2 = getDepFather(y2,f1);
            if(t1 == z1 || t1 == z2 || t2 == z1 || t2 == z2)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }

    }
    return 0;
}




相關推薦

hihocoder [Offer收割]程式設計練習賽19

題目1 : 大禮堂地毯 列舉 #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> using namespace std;

hihoCoder [Offer收割]程式設計練習賽83 D 生成樹問題

題目 從 Kruskal 演算法的角度來思考這個問題。 考慮 $n$ 個點的“空圖”(即沒有邊的圖)。 先將 $m_2$ 條無權值的邊加到圖中,得到一個森林。 將 $m_1$ 條有權值的邊按權值從小到大排序。 列舉這些邊,對於邊 $e\colon(u, v, w)$,若將 $e$ 加入圖中之後 (i)

hihoCoder 1285 [Offer收割]程式設計練習賽3-3

[Offer收割]程式設計練習賽3——第3題 這次練習賽感覺比前兩次練習賽簡單一點,第1第2題就不說了。 #1285 : 智力競賽 時間限制: 5000ms 單點時限: 1000ms

[Offer收割]程式設計練習賽2 hihocoder 1275 掃地機器人 (計算幾何+模擬 比較煩)

時間限制:10000ms 單點時限:1000ms 記憶體限制:256MB 描述 小Ho最近買了一臺掃地機器人用來代替他清掃實驗室的衛生,掃地機器人有不同的尺寸,但是通常來說可以被視作一個M*M的正方形,掃地機器人僅能清掃被自己覆蓋過的區域。 小Ho所在的實驗室是一個

[Offer收割]程式設計練習賽1 hihocoder 1270 建造基地 (完全揹包)

時間限制:10000ms 單點時限:1000ms 記憶體限制:256MB 描述 在遙遠的未來,小Hi成為了地球聯邦外空間聯合開發工作組的一員,前往一顆新發現的星球開發當地的重金屬資源。 為了能

HiHoCoder #1270 : 建造基地 [Offer收割]程式設計練習賽1 【完全揹包】

描述 在遙遠的未來,小Hi成為了地球聯邦外空間聯合開發工作組的一員,前往一顆新發現的星球開發當地的重金屬資源。 為了能夠在當地生存下來,小Hi首先要建立一個基地。建立基地的材料可以直接使用當地的石材和富裕的重金屬資源。基地建設分為N級,每一級都需要達成K的建設值後才能夠完成建設,當前級別的建設值溢位後不會

[Offer收割]程式設計練習賽79——字母去重

[Offer收割]程式設計練習賽79——字母去重 題目 時間限制:10000ms 單點時限:1000ms 記憶體限制:256MB 描述 給定一個字串S,每次操作你可以將其中任意一個字元修改成其他任意字元。 請你計算最少需要多少次操作,才能使得S中不存在兩個相鄰的相同字元。

[Offer收割]程式設計練習賽84 -- 括號序列

時間限制:10000ms 單點時限:1000ms 記憶體限制:256MB 描述 給定一個只包含'(', ')'和''的字串S,現在小Hi可以任意指定''為'('或')',不同的'*'可以是不同的字元。 請你判斷小Hi是否可能得到一個合法匹配的字串。 輸入 第一行包含一個整數T,代表資料的組數。 以

[Offer收割]程式設計練習賽9 B題 水陸距離

題目2 : 水陸距離 時間限制:10000ms 單點時限:1000ms 記憶體限制:256MB 描述 給定一個N x M的01矩陣,其中1表示陸地,0表示水域。對於每一個位置,求出它距離最近的水域的距離是多少。 矩陣中每個位置與它上下左右相鄰的格

[Offer收割]程式設計練習賽49

A.相似顏色 每兩位列舉一下0~15,更新一下就好了。。 #include <bits/stdc++.h> #define FOR(i,a,b) for(int i=(a);i<(b);i++) #define REP(i,a,b)

[Offer收割]程式設計練習賽56:卡片遊戲

#include<bits/stdc++.h> #include <assert.h> using namespace std; const int maxn = 1e5+11

[Offer收割]程式設計練習賽3

/** * ----------------------------------------------------------------- * Copyright (c) 2016 crazyacking.All rights reserved. * ---------------------------

Offer收割]程式設計練習賽15-題目1 : 偶像的條件】

【連結】:https://hihocoder.com/contest/offers15/problems 【題目描述】: 題目1 : 偶像的條件 時間限制:10000ms 單點時限:1000ms 記憶體限制:256MB 描述 小Hi的學校正面臨著廢

[Offer收割]程式設計練習賽4

    #include <iostream> #include <string.h> #include <string> using namespace std; int main() { int n,x; int a[25]; cin >&

[Offer收割]程式設計練習賽27:題目2 : 兩個機器人

描述 一個N × M的2D迷宮中有兩個機器人。機器人A在迷宮左上角,只能向右或向下移動;機器人B在迷宮右下角,只能向左或向上移動。機器人不能移動到迷宮外。此外,由於奇怪的同步機制,這兩個機器人只能同時向相反的方向移動。也就是說或者機器人A向右同時機器人B向左;或者機器人A向下同時機器人B向上移動。   迷

九宮(DFS)——hiho [Offer收割]程式設計練習賽1

描述 小Hi最近在教鄰居家的小朋友小學奧數,而最近正好講述到了三階幻方這個部分,三階幻方指的是將1~9不重複的填入一個3*3的矩陣當中,使得每一行、每一列和每一條對角線的和都是相同的。 三階幻方又被稱作九宮格,在小學奧數裡有一句非常有名的口訣:“二四為肩,六八為足,左三右七,戴九履一,五居其中”,通過這樣

[Offer收割]程式設計練習賽79

題目 題目1: 題意: 給定一個字串S,每次操作你可以將其中任意一個字元修改成其他任意字元,請你計算最少需要多少次操作,才能使得S中不存在兩個相鄰的相同字元。 思路: 從第二個字元往後,如果字元相同ans+1。因為s[i]的改變會對s[i-1],s[i+1]都產

hihocoder1368即 [Offer收割]程式設計練習賽7第四題

hihocoder1368即 [Offer收割]程式設計練習賽7第四題: 積水的城市2 時間限制:10000ms 單點時限:1000ms 記憶體限制:256MB 描述 提示:本題與“積水的城市”相比,資料範圍擴大了。 如下圖所示,某市市區由M條南

[Offer收割]程式設計練習賽29 題目1 : 逃離迷宮4

描述 小Hi被壞女巫抓進一座由無限多個格子組成的矩陣迷宮。 小Hi一開始處於迷宮(x, y)的位置,迷宮的出口在(a, b)。小Hi發現迷宮被女巫施加了魔法,假設當前他處在(x, y)的位置,那麼他只能移動到(x+y, y)或者(x, x+y)的位置上。 小Hi想知道自己能不能逃離迷宮。 輸入 第一行包

hihocoder1496 尋找最大值(offer收割程式設計練習賽12D)

題目大意:在1e5個數裡尋找兩個數a[i],a[j] ,(i!=j )使得 a[i] * a[j] * (a[i]&a[j]) 為最大值。 思路:對於a[i]&num,在a[i]的二進位制位下來說,不會使a[i]&num==0的應該