zoukankan      html  css  js  c++  java
  • BestCoder Round #89

      过了这么久才来写……

      BC的后两道题好难……(第二道题也不怎么简单……)

    1001 Fxx and string

      正着倒着枚举一次就ok

      

    #include<iostream>
    #include<cstdio>
    #include<map>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define N 10005
    char a[N];
    int main() {
        int T,len,ans;
        scanf("%d",&T);
        while(T--) {
            scanf("%s",a+1);
            len = strlen(a+1);
            ans = 0;
            for(int i = 1;i <= len;i++){
                if(a[i] != 'y') continue;
                for(int k = 1;true;k++){
                    if(i*k*k > len) break;
                    if(a[i*k]=='r' && a[i*k*k]=='x') ans++;
                }
            }
            for(int i = 1;i <= len;i++){
                if(a[i] != 'x') continue;
                for(int k = 1;true;k++){
                    if(i*k*k > len) break;
                    if(a[i*k]=='r' && a[i*k*k]=='y') ans++;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

      这个题更新数据以后,爆搜肯定挂,比如(1000000,1,100000)

      所以要用dp,dp[x] = min(dp[x-i],dp[x/k]) ,1<=i<=t,容易想明白,但是暴力转移肯定挂,至于线段树,我帮你们写了,也挂……

      所以只能维护单调队列来优化这个dp

      维护[x-t,x-1]之间的单调队列,使其从队头到队尾是递增的,然后正常转移,更新单调队列就可以(单调队列在dp里的用处真的很大)

      单调队列代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<deque>
    using namespace std;
    const int INF = 1e9;
    const int N = 1e6+6;
    int dp[N],n,k,t;
    deque<int> dq; ///维护一个从队尾到队头 递减的队列
    int main() {
        int T,x;
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d%d",&n,&k,&t);
            dp[1]=0;
            while(!dq.empty()) dq.pop_back();
            dq.push_back(1);
            for(int i=2; i<=n; i++) {
                dp[i]=INF;
                if(i%k==0) dp[i]=min(dp[i],dp[i/k]+1);
                while(!dq.empty()) {
                    x=dq.front();
                    if(x<i-t||x>i-1) dq.pop_front();
                    else break;
                }
                if(!dq.empty()) dp[i]=min(dp[i],dp[x]+1);
                while(!dq.empty()) {
                    x=dq.back();
                    if(dp[x]>=dp[i]) {
                        dq.pop_back();
                    } else break;
                }
                dq.push_back(i);
            }
            printf("%d
    ",dp[n]);
        }
        return 0;
    }
    View Code

      挂了的线段树代码(笑哭)

    #include<iostream>
    #include<cstdio>
    #include<map>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N = 1e6+5;
    #define lc 2*node
    #define rc 2*node+1
    #define MAX 1e9
    int seg[N*4+10],dp[N];
    void Build(int node,int l,int r){
        if(l == r) seg[node] = MAX;
        else {
            int mid = (l+r)>>1;
            Build(lc,l,mid);
            Build(rc,mid+1,r);
            seg[node] = min(seg[lc],seg[rc]);
        }
    }
    void Update(int node,int l,int r,int k,int num){
        if(l==r) {
           seg[node] = num;
           return;
        }
        int mid = (l+r)>>1;
        if(k <= mid) Update(lc,l,mid,k,num);
        else Update(rc,mid+1,r,k,num);
        seg[node] = min(seg[lc],seg[rc]);
    }
    int query(int node,int l,int r,int ql,int qr){
        int p1,p2;
        if(ql > r || qr < l) return MAX;
        if(l >= ql && r <= qr) return seg[node];
        int mid = (l+r)>>1;
        p1 = query(lc,l,mid,ql,qr);
        p2 = query(rc,mid+1,r,ql,qr);
        return min(p1,p2);
    }
    int main()
    {
        int T,x,k,t;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d%d",&x,&k,&t);
            Build(1,1,x);
            dp[1] = 0;
            Update(1,1,x,1,dp[1]);
            for(int i = 2;i <= x;i++){
                int q = query(1,1,x,i-t,i-1);
                dp[i] = q+1;
                if(i % k == 0) dp[i] = min(dp[i],dp[i/k]+1);
                Update(1,1,x,i,dp[i]);
            }
            printf("%d
    ",dp[x]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    好兴奋,我的博客终于上线了
    学技术,该怎么看书
    PHP程序员求职经验总结
    Jquery中extend使用技巧
    JavaScript(JS)实现省市联动选择下拉列表
    银行家算法之JavaScript实现
    JS中的两种刷新方法以及区别和适用范围
    一段上传图片预览JS脚本,Input file图片预览的实现
    本博客模板说明
    深圳,想说爱你不容易!
  • 原文地址:https://www.cnblogs.com/jifahu/p/6202361.html
Copyright © 2011-2022 走看看