zoukankan      html  css  js  c++  java
  • 2021“MINIEYE杯”中国大学生算法设计超级联赛(4)

    hoj暑期第四场

    1001

    • 题意

    给你定义一个函数
    math.svg
    然后,(S(x)=sum_{j=1}^xf(j)), 求 (lim limits_{x o infty}S(x)=c) , s(x)中x趋近正无穷的极限得是个常数

    • 思路

    非常难受,就这种题,还有人能wa4,5发的啊。呜呜呜呜呜

    code:

    void solve(){
        string str;
        cin >> str;
        bool flag = 0;
        for(int i = 0;i < str.size();i ++) {
            if(isdigit(str[i]) && str[i] != '0') {
                flag = 1;
                break;
            }
        }
        if(!flag) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    

    1002

    • 题意

    就是给你一颗树,每个节点都有一个颜色,定义(a_i,_j)表示从节点i到节点j颜色不同的数量,让你求
    (f(i,19560929)=sum_{j=1}^n a_{i,j}x^{j-1})
    这个公式中mod ((10^9+7)) 和 ((10^9+9))得出的不同值。

    • 思路

    emmm,我就是用以每个点为根,扫了一边dfs后加个预处理就过了昂()

    code:

    const int N = 2010;
    const double INF = 1e9;
    const int M = 2 * N;
    ll ans[N][2];
    ll f[N][N];
    ll sum1[N], sum2[N];
    int h[N],e[M],ne[M],w[N],idx;
    bool st[N];
    
    void add(int a,int b) {
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    }
    int root;
    void dfs(int u,int fa,int val) {
        for(int i = h[u];~i;i = ne[i]) {
            int j = e[i];
            if(j == fa) continue;
            f[root][j] = val;
            bool flag = 0;
            if(!st[w[j]]) {
                st[w[j]] = 1;
                flag = 1;
                f[root][j] ++;
            }
            dfs(j,u,f[root][j]);
            if(flag) {
                st[w[j]] = 0;
            }
        }
    }
    
    void init() {
        ll x = 19560929;
        ll mod = 1e9 + 7;
        sum1[0] = 1;
        for(int i = 1;i <= 2000;i ++) {
            sum1[i] = sum1[i - 1] * x % mod;
        }
        mod = 1e9 + 9;
        sum2[0] = 1;
        for(int i = 1;i <= 2000;i ++) {
            sum2[i] = sum2[i - 1] * x % mod;
        }
        
    }
    
    void solve(){
        int n;
        scanf("%d", &n);
        idx = 0;
        memset(h,-1,sizeof h);
        for(int i = 2;i <= n;i ++) {
            int x;
            scanf("%d", &x);
            add(i,x), add(x,i);
        }
        for(int i = 1;i <= n;i ++) scanf("%d", &w[i]);
        for(int i = 1;i <= n;i ++) {
            root = i;
            f[i][i] = 1;
            st[w[i]] = 1;
            dfs(i,-1,1);
            st[w[i]] = 0;
        }
        for(int i = 1; i <= n;i++){
            ll sum = 0;
        	ll x = 19560929;
        	ll mod = 1e9 + 7;
        	for(int j = 1; j <= n; j++){
        		sum = (sum + f[i][j]%mod*sum1[j-1]%mod + mod)%mod;
    		}
    		sum %= mod;
    		ans[i][0] = sum;
    		 
    		mod = 1e9 + 9;
    		sum = 0;
        	for(int j = 1; j <= n; j++){
        		sum = (sum + f[i][j]*sum2[j-1]%mod + mod)%mod;
    		}
    		sum %= mod;
    		ans[i][1] = sum; 
        }
        for(int i = 1; i <= n; i++){
            cout << ans[i][0] << " " << ans[i][1] << endl;
        }
    }
    

    1008

    • 题意

    一个僵尸,在(n * m)的地图的地图中走,并且只能想下和向右走,并且其中有k个障碍物,问你僵尸从(1,1)开始能到的所有点的数量

    数据范围:(1<=t<=20) , (2<= n,m,k<= 10^5)

    • 思路

    考场上是按题解写的(用线段树维护上一层不能向下走的集合),没调出来,还是t了,当时是k(log^2n写的),后面看std,又是维护上一层可行(可以向下走)的区域,都差不多吧~, 按照std的思想又码了一遍,还是太菜了,这个query和update中按照情况,还是L,R进行变动这个没想出来啊,呜呜呜--

    code:

    const int N = 100100;
    const double INF = 1e9;
    
    
    ll sum[2][N << 2],laz[2][N << 2];
    
    void build(int u,int l,int r) {
        sum[0][u] = sum[1][u] = 0;
        laz[0][u] = laz[1][u] = -1;
        if(l == r) {
            return;
        }
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1,r);
    }
     
    void down(int u,int l,int r, int k){
        if(laz[k][u] == -1) return;
        int mid = l + r >> 1;
        
        ll la = laz[k][u];
        sum[k][u << 1] = la * (mid - l + 1);
        sum[k][u << 1 | 1] = la * (r - mid);
        
        laz[k][u << 1] = la;
        laz[k][u << 1 | 1] = la;
        
        laz[k][u] = -1;
    }
    
    void update(int L,int R,ll v,int u,int l,int r,int k){
        if(l >= L && r <= R){
            sum[k][u] = v * (r - l + 1);
            laz[k][u] = v;
            return;
        }
        down(u,l,r,k);
        int mid = l + r >> 1;
        if(R <= mid) update(L, R, v, u << 1, l, mid,k);
        else if(L > mid) update(L, R, v, u << 1 | 1,mid + 1, r,k);
        else {
            update(L,mid,v,u << 1,l,mid,k);
            update(mid + 1,R,v,u << 1 | 1,mid + 1,r,k);
        }
        sum[k][u] = (sum[k][u << 1] + sum[k][u << 1 | 1]);
    }
    
    ll query(int L,int R,int u,int l,int r,int k){
        if(!sum[k][u]) return INF;
        if(l == r) return l;
        down(u,l,r,k);
        int mid = l + r >> 1;
        if(l >= L && r <= R){
            if(sum[k][u << 1] > 0) return query(l,mid,u << 1,l, mid,k);
            else return query(mid + 1, r, u << 1 | 1, mid + 1, r,k);
        }
        if(R <= mid) return query(L,R,u << 1,l,mid,k);
        else if(L > mid) return query(L,R,u << 1 | 1, mid + 1, r,k);
        else return min(query(L,mid,u << 1,l,mid,k), query(mid + 1,R,u << 1 | 1, mid + 1, r,k));
    }
    
    
    vi p[N];
    
    void solve(){
        int n,m,k;
        cin >> n >> m >> k;
        for(int i = 1;i <= k;i ++) {
            int a,b;
            cin >> a >> b;
            p[a].pb(b);
        }
        ll ans = 0;
        build(1,1,m);
        update(1,m,1,1,1,m,1); // 起点是可以的
        if(p[1].size()) {
            sort(p[1].begin(), p[1].end());
            update(p[1][0], m,0,1,1,m,1);
        }
        ans += sum[1][1];
        // 通过上一行的可行区域计算下一行的可行区域
        for(int i = 2;i <= n;i ++) {
            int l = 0;
            sort(p[i].begin(), p[i].end());
            for(int it : p[i]) {
                if(it > l + 1) {
                    int pos = query(l + 1, it - 1, 1, 1, m,(i & 1) ^ 1); // 找上一层在l + 1 ~ it - 1之中,可行的最靠左的点
                    if(pos != INF) update(pos, it - 1, 1, 1, 1, m ,i & 1); // 那么左端点到it - 1都是可到达的区域
                }
                l = it;
            }
            if(l + 1 <= m) {
                int pos = query(l + 1,m,1,1,m,(i & 1) ^ 1); // 同上
                if(pos != INF) update(pos,m,1,1,1,m,i & 1);
            }
            ans += sum[i & 1][1];
            update(1,m,0,1,1,m,(i & 1) ^ 1); // 清空,为下一层做准备
        }
        cout << ans << endl;
        for(int i = 1;i <= n;i ++) p[i].clear();
    }
    

    1009

    • 题意

    给你30行字符串,每行100列,并且是个车牌,后5位字母或数组,第2位字母,第1位汉字。

    • 思路

    for两层,第一层从后往前,记录答案,最后第7个的时候不用记录,让l,r在那,然后输出即可也就汉字能让我wa一发了0.0

    code:

    string str[31];
    
    vector<pii> ans;
    int now;
    void solve(){
        for(int i = 0;i < 30;i ++) {
            cin >> str[i];
        }
        
        cout << "Case #" << (++ now) << ":" << endl;
        int l = 0,r = 0;
        for(int i = str[0].size() - 1;i >= 0;i --) {
            bool flag = 0;
            for(int j = 0;j < 30;j ++) {
                if(str[j][i] != '.') {
                    flag = 1;
                    break;
                }
            }
            if(flag && !l) l = i + 1;
            else if(flag) r = i + 1;
            
            if(!flag && l && r && ans.size() < 6) {
                ans.push_back({r,l});
                l = 0,r = 0;
            }
        }
        cout << r << ' ' << l << endl;
        for(int i = 5;i >= 0;i --) {
            cout << ans[i].first << ' ' << ans[i].second << endl;
        }
        ans.clear();
    }
    
  • 相关阅读:
    Video视频播放中断问题排查记录
    下一站:手机安全
    数据之美 之一
    数据之美 之二
    数据之美 之三
    Groovy入门
    Java8新特性(Lambda表达式、Stream流、Optional类)等
    websocket和ajax的区别(和http的区别)
    java泛型<? extends E>和<? super E>的区别和适用场景
    JAVA反射
  • 原文地址:https://www.cnblogs.com/darker-wxl/p/15077088.html
Copyright © 2011-2022 走看看