zoukankan      html  css  js  c++  java
  • HGOI 20200906

    9月了,时间不多了,写写博客记录生活

    今天虽然A了一题,但是其他两题都接近0分,总分不好啊

    T1

    这个大模拟!

    开始看错题了
    以为要写编译器果断切题
    切了T2后仔细一看woc原来就是图+模拟
    懵了
    写完了但0分
    血亏

    就一个模拟+记搜就行了

    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define per(i, a, b) for (int i = a; i >= b; i--)
    #define siz(a) (int)a.size()
    #define pb push_back
    #define mp make_pair
    #define ll long long
    #define fi first
    #define se second
    
    const int N = 100010 ;
    
    int n ;
    
    signed main() {
        int T; scanf("%d", &T) ;
        while (T--) {
            bool segmentation_fault = false;
            bool compile_error = false;
            map<string, unsigned ll> fn;
            set<string> seg;
            scanf("%d", &n) ;
            string s;
            for (int i = 0; i <= 3; i++) getline(cin, s);
            fn["A"] = 1;
            fn["printf"] = 0;
            for (int cnt = 3; cnt < n;) {
                getline(cin, s);
                cnt++;
                stringstream sss;
                sss << s;
                sss >> s;
                while (sss.peek() == ' ') sss.get();
                getline(sss, s, '(');
                if (fn.count(s)) compile_error = true;
                const string func = s;
                const map<string, unsigned ll>::iterator it = fn.insert({ s, 0 }).first;
                if (func == "main") {
                    getline(cin, s);
                    cnt++;
                }
                while (cnt < n) {
                    getline(cin, s);
                    cnt++;
                    if (s == "}") break;
                    stringstream ss;
                    ss.clear();
                    ss << s;
                    while (ss.peek() == ' ') ss.get();
                    getline(ss, s, '(');
                    if (s == func || seg.count(s)) {
                        seg.insert(func);
                        if (func == "main") segmentation_fault = true;
                    }
                    if (!fn.count(s)) compile_error = true;
                    else it->second += fn[s];
                }
            }
            if (compile_error) cout << "Compile error
    ";
            else if (segmentation_fault) cout << "Segmentation fault
    ";
            else cout << fn["main"] << '
    ';
        }
        return 0;
    }
    

    T2

    A了这题!

    算法都不难,合一起就容易错

    先求出最短路图

    然后在对短路上求概率

    p[i][j]表示第i个势力到第j个位置的概率

    考虑求出每个位置的答案

    逆向思维

    ans[i]=1-没有人经过此地-一个势力的两只队伍同时经过此地
    前者很明显就是(1-p[][i])的累乘
    后者就是累乘扣掉某一个(1-p[k][i])再乘p[k][i]

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define per(i, a, b) for (int i = a; i >= b; i--)
    #define siz(a) (int)a.size()
    #define pb push_back
    #define mp make_pair
    #define ll long long
    #define fi first
    #define se second
    
    const int N = 3010 ;
    const int mod = 998244353 ;
    
    int n, m, k, cnt, sz ;
    int head[N], heads[N], headn[N] ;
    int deg[N], vis[N], dis[N], pf[N] ;
    int inv[N], pp[N], ps[N], ans[N] ;
    int p[N][N << 2] ;
    
    struct Edge {
    	int to, nxt ;
    } e[N << 2], es[N << 2], en[N << 2] ;
    
    void add(int a, int b) {
    	e[++cnt].to = b ; e[cnt].nxt = head[a] ; head[a] = cnt ;
    }
    
    void addedge(int a, int b) {
    	es[++cnt].to = b ; es[cnt].nxt = heads[a] ; heads[a] = cnt ;
    	en[cnt].to = a ; en[cnt].nxt = headn[b] ; headn[b] = cnt ;
    	deg[b]++ ;
    }
    
    queue <int> q ;
    
    void spfa(int a) {
    	while (!q.empty()) q.pop() ;
    	q.push(a) ; dis[a] = 0 ;
    	while (!q.empty()) {
    		int u = q.front() ; q.pop() ;
    		vis[u] = 0 ;
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to ;
    			if (dis[v] > dis[u] + 1) {
    				dis[v] = dis[u] + 1 ;
    				if (!vis[v]) {
    					vis[v] = 1 ;
    					q.push(v) ;
    				}
     			}
    		}
    	}
    }
    
    void get() {
    	cnt = 0 ;
    	memset(heads, 0, sizeof(heads)) ;
    	memset(headn, 0, sizeof(headn)) ;
    	memset(deg, 0, sizeof(deg)) ;
    	rep(i, 1, n)
    	for (int j = head[i]; j; j = e[j].nxt) 
    	if (dis[i] + 1 == dis[e[j].to]) addedge(i, e[j].to) ;
    } 
    
    void rev(int b) {
    	memset(vis, 0, sizeof(vis)) ;
    	while (!q.empty()) q.pop() ;
    	q.push(b) ; vis[b] = 1 ;
    	while (!q.empty()) {
    		int u = q.front() ; q.pop() ;
    		for (int i = headn[u]; i; i = en[i].nxt)
    		if (!vis[en[i].to]) {
    			vis[en[i].to] = 1 ;
    			q.push(en[i].to) ;
    		}
    	} 
    }
    
    void calc(int c, int a) {
    	int tot = 0 ;
    	memset(pf, 0, sizeof(pf)) ;
    	while (!q.empty()) q.pop() ;
    	q.push(a) ; pf[a] = 1 ;
    	while (!q.empty()) {
    		int u = q.front() ; q.pop() ;
    		tot = 0 ;
    		for (int i = heads[u]; i; i = es[i].nxt) 
    		if (deg[es[i].to] && vis[es[i].to]) tot++ ;
    		for (int i = heads[u]; i; i = es[i].nxt) 
    		if (vis[es[i].to] && deg[es[i].to]) {
    			int v = es[i].to ;
    			deg[v]-- ;
    			pf[v] = (pf[v] + pf[u] * inv[tot] % mod) % mod ;
    			if (!deg[v]) q.push(v) ;
    		} 
    	}
    	rep(i, 1, n) p[c][i] = p[c][i] * ((1 - pf[i] + mod) % mod) % mod ;
    }
    
    signed main() {
    //	freopen("sukeban.in", "r", stdin) ;
    //	freopen("sukeban.out", "w", stdout) ;
    	inv[0] = inv[1] = 1 ;
    	rep(i, 2, 1000) inv[i] = (mod - mod / i) * inv[mod % i] % mod ;
    	int t ; scanf("%lld", &t) ;
    	while (t--) {
    		memset(head, 0, sizeof(head)) ;
    		cnt = 0 ;
    		scanf("%lld%lld%lld", &n, &m, &k) ;
    		rep(i, 1, m) {
    			int x, y ; scanf("%lld%lld", &x, &y) ;
    			add(x, y) ; add(y, x) ;
    		}
    		rep(j, 1, n) rep(i, 1, k) p[i][j] = 1 ;
    		sz = 0 ;
    		rep(i, 1, k) {
    			int c, a, b ; scanf("%lld%lld%lld", &c, &a, &b) ;
    			sz = max(sz, c) ;
    			memset(dis, 0x3f, sizeof(dis)) ;
    			memset(vis, 0, sizeof(vis)) ;
    			spfa(a) ;
    			get() ;
    			rev(b) ;
    			calc(c, a) ;
    		}
    		memset(ans, 0, sizeof(ans)) ;
    		rep(i, 1, n) {
    			pp[0] = ps[sz + 1] = 1ll ;
    			rep(j, 1, sz) pp[j] = pp[j - 1] * p[j][i] % mod ;
    			per(j, sz, 1) ps[j] = ps[j + 1] * p[j][i] % mod ;
    			ans[i] = ps[1] ;
    			rep(j, 1, sz) ans[i] = (ans[i] + pp[j - 1] * ps[j + 1] % mod * (1 - p[j][i] + mod) % mod) % mod ;
    			printf("%lld
    ", (1 - ans[i] + mod) % mod) ;
    		} 
    	}
    	return 0 ;
    }
    

    T3

    还不会
    O(N^3)会不想写

    复制solution+std

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    #include <cstdlib>
    #define LL long long
    #define LD long double
    using namespace std;
    const int NN = 30000 + 117;
    const int SQRTN = 200;
    const int MM = +117;
    int read() {
        int fl = 1, x;
        char c;
        for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
            ;
        if (c == '-') {
            fl = -1;
            c = getchar();
        }
        for (x = 0; c >= '0' && c <= '9'; c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        return x * fl;
    }
    void open() {
        freopen("ex_mito2.in", "r", stdin);
        // freopen("mito.out","w",stdout);
    }
    void close() {
        fclose(stdin);
        fclose(stdout);
    }
    
    int m, n;
    struct node {
        int f, r;
        int pos;
    } a[NN];
    bool cmp(node a, node b) {
        if (a.f != b.f)
            return a.f < b.f;
        if (a.r != b.r)
            return a.r < b.r;
        return a.pos < b.pos;
    }
    vector<int> ls;
    struct edge {
        int to, len;
        edge(int t = 0, int l = 0) { to = t, len = l; }
    };
    vector<edge> p[NN * SQRTN];
    int pcnt;
    int pt[NN] = {};
    void build(int f, int rem) {
        for (int i = rem; i < n; i += f) {
            ++pcnt;
            pt[i] = pcnt;
        }
        for (int i = rem; i < n; i += f) {
            if (i - f >= 0)
                p[pt[i]].push_back(edge(pt[i - f], 1));
            if (i + f < n)
                p[pt[i]].push_back(edge(pt[i + f], 1));
        }
        int pos = 0;
        for (int i = rem; i < n; i += f) {
            while (pos != ls.size() && ls[pos] < i) ++pos;
            int dis = 1e9;
            if (pos != ls.size())
                dis = min(dis, (ls[pos] - i) / f);
            if (pos)
                dis = min(dis, (i - ls[pos - 1]) / f);
            p[i].push_back(edge(pt[i], dis));
            p[pt[i]].push_back(edge(i, 0));
        }
        /*
        for(int i=0;i<ls.size();++i){
                int k=ls[i];
                p[k].push_back(edge(pt[k],0));
        }
        */
    }
    struct spnode {
        int pt, dis;
        spnode(int p = 0, int d = 0) { pt = p, dis = d; }
    };
    struct spcmp {
        bool operator()(spnode a, spnode b) { return a.dis > b.dis; }
    };
    priority_queue<spnode, vector<spnode>, spcmp> q;
    int sp[NN * SQRTN] = {};
    void getsp(int st) {
        for (int i = 0; i <= pcnt; ++i) {
            sp[i] = 1e9;
        }
        sp[st] = 0;
        q.push(spnode(st, 0));
        while (!q.empty()) {
            if (sp[q.top().pt] < q.top().dis) {
                q.pop();
                continue;
            }
            int x = q.top().pt;
            q.pop();
            for (int i = 0; i < p[x].size(); ++i) {
                int cur = p[x][i].to;
                if (sp[cur] > sp[x] + p[x][i].len) {
                    sp[cur] = sp[x] + p[x][i].len;
                    q.push(spnode(cur, sp[cur]));
                }
            }
        }
    }
    int main() {
        open();
        n = read();
        m = read();
        for (int i = 1; i <= m; ++i) {
            a[i].pos = read();
            a[i].f = read();
            a[i].r = a[i].pos % a[i].f;
        }
        int start = a[1].pos;
        int final = a[2].pos;
        int freq = a[2].f;
        sort(a + 1, a + 1 + m, cmp);
        ls.push_back(a[1].pos);
        int nf = a[1].f;
        int nr = a[1].r;
        pcnt = n;
        for (int i = 2; i <= m + 1; ++i) {
            if (a[i].f == nf && a[i].r == nr) {
                ls.push_back(a[i].pos);
            } else {
                build(nf, nr);
                nf = a[i].f;
                nr = a[i].r;
                ls.clear();
                ls.push_back(a[i].pos);
            }
        }
        getsp(start);
        int ans = 1e9;
        for (int i = final % freq; i < n; i += freq) {
            ans = min(ans, (sp[i] + abs(i - final) / freq));
        }
        /*ans=sp[final];*/
        if (ans >= 1e8)
            printf("-1
    ");
        else
            printf("%d
    ", ans);
        close();
        return 0;
    }
    
    
  • 相关阅读:
    OpenCV/python读取,显示,保存图像
    机器学习的基本分类
    Qt Designer常用部件介绍
    C#数据类型列表
    SQL-Base 函数
    SQl 基本函数
    SQL 插入数据
    SQL-Base 用表组织数据
    SQLserver的基本用法
    C#MyBank(自己的看法,转账有点小问题)
  • 原文地址:https://www.cnblogs.com/harryhqg/p/13621732.html
Copyright © 2011-2022 走看看