zoukankan      html  css  js  c++  java
  • 牛客寒假训练三

    两种方法,递归和递推

    记忆化搜索跑一边就行了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    const ll N=100;
    ll dp[N][N];
    char arr[N][N];
    ll n,m;
    bool flag=0;
    ll dfs(ll x,ll y)
    {
        if(dp[x][y]) return dp[x][y]%mod;
        if(arr[x][y]=='R'&&y+1<=m) dp[x][y]=(dp[x][y]+dfs(x,y+1))%mod;
        if(arr[x][y]=='D'&&x+1<=n) dp[x][y]=(dp[x][y]+dfs(x+1,y))%mod;
        if(arr[x][y]=='B') {
            if(x+1<=n) dp[x][y]=(dp[x][y]+dfs(x+1,y))%mod;
            if(y+1<=m)dp[x][y]=(dp[x][y]+dfs(x,y+1))%mod;
        }
        return dp[x][y]%mod;
    }
    int main()
    {
    
        cin>>n>>m;
        for(ll i=1;i<=n;i++) scanf("%s",arr[i]+1);
        dp[n][m]=1;
        ll x=dfs(1,1)%mod;
        cout<<x<<endl;
    
        return 0;
    }

    递推,o(n^2),遍历每一个点,同时判断每一个点的上一个状态。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    const ll N=70;
    char arr[N][N];
    ll dp[N][N];
    int main()
    {
        ll n,m;
        cin>>n>>m;
        for(ll i=1;i<=n;i++) scanf("%s",arr[i]+1);
        dp[1][1]=1;
        for(ll i=1;i<=n;i++){
            for(ll j=1;j<=m;j++){
                if(arr[i][j-1]=='R'||arr[i][j-1]=='B') dp[i][j]=(dp[i][j]+dp[i][j-1])%mod;
                if(arr[i-1][j]=='D'||arr[i-1][j]=='B') dp[i][j]=(dp[i][j]+dp[i-1][j])%mod;
            }
        }
        cout<<dp[n][m]%mod<<endl;
        return 0;
    }

    B 待补

    C,水,提交之前最好用自测功能试一下。。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=1E3+7;
    ll arr[N][N];
    void solve(){
        ll n,m,p;
        cin>>n>>m>>p;
        bool re=0;
        bool Be=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                arr[i][j]=0;
        }
        while(p--){
            ll x,y,v;
            cin>>x>>y>>v;
            if(re) continue ;
            if(x<0||y<0||x>=n||y>=m) Be=1;
            ll c=m*x+y;
            if(c>m*(n-1)+m-1||c<0) {
                re=1;
            }
            else {
                arr[c/m][c%m]=v;
            }
        }
        if(re) cout<<"Runtime error"<<endl;
        else if(Be){
            for(ll i=0;i<n;i++){
                for(ll j=0;j<m;j++){
                    cout<<arr[i][j];
                    if(j==m-1) break ;
                    cout<<" ";
                }
                cout<<endl;
            }
            cout<<"Undefined Behaviour"<<endl;
        }
        else {
            for(ll i=0;i<n;i++){
                for(ll j=0;j<m;j++){
                    cout<<arr[i][j];
                    if(j==m-1) break;
                    cout<<" ";
                }
                cout<<endl;
            }
            cout<<"Accepted"<<endl;
        }
    }
     
    int main(){
        int t;
        cin>>t;
        while(t--) solve();
        return 0;
    }

    D 水

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1E5+7;
    int arr[N];
    int brr[N];
    int main(){
        int n;
        cin>>n;
        int s=0;
        for(int i=1;i<=n;i++){
            cin>>arr[i];
            if(arr[i]==-1) continue ;
            s++;
            brr[arr[i]]=i;
        }
        printf("The size of the tree is %d
    ",s);
        printf("Node %d is the root node of the tree
    ",arr[1]);
        bool father=0;
    
        for(int i=1;i<=s;i++){
            int c=brr[i];
            if(c/2==0){
                printf("The father of node %d is -1, ",i);
            }
            else {
                printf("The father of node %d is %d, ",i,arr[c/2]);
            }
            if(2*c>n) printf("the left child is -1, ");
            else {
                printf("the left child is %d, ",arr[2*c]);
            }
            if(2*c+1>n) printf("and the right child is -1");
            else {
                printf("and the right child is %d",arr[2*c+1]);
            }
            if(i==s) continue ;
            cout<<endl;
        }
        return 0;
    }

    E 待补

    保存1的位置,求前缀和,可以直接求,也可以套线段树。答案就是1前面的1的个数乘以当前1的位置数再减去当前1前面1的位置的前缀和,然后累加。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    const ll N=1E5+7;
    ll arr[N];
    ll dp[N];
    int main()
    {
        ll n;
        cin>>n;
        string s;
        cin>>s;
        ll pos=0;
        for(ll i=0;i<n;i++) {
            if(s[i]=='1') arr[pos++]=i;
        }
        if(pos==1){
            cout<<0<<endl;
            return 0;
        }
        dp[0]=arr[0];
        for(ll i=1;i<pos;i++) dp[i]=arr[i]+dp[i-1];
        ll sum=0;
        for(ll i=pos-1;i>=0;i--){
            sum=(sum+i*arr[i])%mod;
            sum=(sum-dp[i-1]+mod)%mod;
        }
        cout<<(sum+mod)%mod<<endl;
        return 0;
    }

    F

    线段树,

    假设初始状态 有4个1,其位置分别为a b c d e,此时答案为ans,在cd之间插入了一个e1那么新增加的对为e-e1+d-e1+e1-c+e1-b+e1-a。所以答案为e1后边的数的和减去e1*e1后边1的个数加上e1*e1左边1的个数再减去从1到c的和。所以我们可以用线段树的方法维护区间和。在这里我们维护两个线段树,第一个为位置前缀和,第二个为1的个数的前缀和。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=1E5+7;
    const ll mod=1E9+7;
    ll arr[N];
    ll tree[N+N+N];
    ll t1[N+N+N];
    void buid_tree(ll node,ll start,ll end){//建树
        if(start==end){
            tree[node]=arr[end];
            if(arr[end]!=0) t1[node]=1;
            else t1[node]=0;
            return ;
        }
        ll mid=(start+end)>>1;
        ll left_node  =2*node;
        ll right_node =2*node+1;
        buid_tree(left_node ,start,mid);
        buid_tree(right_node,mid+1,end);
        tree[node]=(tree[left_node]+tree[right_node])%mod;
        t1[node]=t1[left_node]+t1[right_node];
    }
    void update(ll node,ll start,ll end,ll idx,ll value){//节点更新
    
        if(start==end) {
            arr[idx]=(arr[idx]+value+mod)%mod;
            tree[node]=(tree[node]+value+mod)%mod;
            if(arr[idx]==0) t1[node]--;
            else t1[node]++;
            return ;
        }
        ll mid=(start+end) / 2 ;
        ll left_node=2*node;
        ll right_node=2*node+1;
        if(idx>=start && idx<=mid)    update(left_node,start,mid,idx,value);
        else update(right_node,mid+1,end,idx,value);
        tree[node]=(tree[left_node]+tree[right_node]+mod)%mod;
        t1[node]=t1[left_node]+t1[right_node];
    }
    
    ll  query_tree(ll node,ll start,ll end,ll l,ll r,bool x){//查询函数
        if(l>end||r<start) return 0;
        else if(start==end||l<=start&&end<=r){
            if(x==1) return (tree[node]+mod)%mod;
            else return t1[node];
        }
        ll mid=(start+end)/2;
        ll left_node=2*node;//左儿子
        ll right_node=2*node+1;//右儿子
        ll sum_left=query_tree(left_node,start,mid,l,r,x);
        ll sum_right=query_tree(right_node,mid+1,end,l,r,x);
        return (sum_left+sum_right+mod)%mod;
    }
    int main(){
        ios::sync_with_stdio(false);
        ll n;
        cin>>n;
        string s;
        cin>>s;
        for(ll i=0;i<n;i++){
            if(s[i]=='1') arr[i+1]=i+1;
            else arr[i+1]=0;
        }
        buid_tree(1,1,n);
        ll ans=0;
        for(ll i=n;i>=1;i--){
            if(arr[i]==0) continue ;
            ll sum_left=query_tree(1,1,n,1,i,1);
            ll sum_1   =query_tree(1,1,n,1,i,0);
            ans=(ans+sum_1*i-sum_left)%mod;
        }
        ans=(ans+mod)%mod;
        cout<<ans<<endl;
        ll m;
        cin>>m;
        while(m--){
            ll x,y;
            cin>>x>>y;
            if(x==1){
               update(1,1,n,y,y);
               ll sum_left=query_tree(1,1,n,1,y-1,1);
               ll sum_l1=query_tree(1,1,n,1,y-1,0);
               ll sum_right=query_tree(1,1,n,y+1,n,1);
               ll sum_r1=query_tree(1,1,n,y+1,n,0);
               ll x=(sum_l1*y-sum_left+sum_right-sum_r1*y+mod)%mod;
               ans=(ans+x+mod)%mod;
            }
            else {
               update(1,1,n,y,-y);
               ll sum_left=query_tree(1,1,n,1,y-1,1);
               ll sum_l1=query_tree(1,1,n,1,y-1,0);
               ll sum_right=query_tree(1,1,n,y+1,n,1);
               ll sum_r1=query_tree(1,1,n,y+1,n,0);
               ll x=(sum_l1*y-sum_left+sum_right-sum_r1*y+mod)%mod;
               ans=(ans-x+mod)%mod;
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    H题:

    这个题目就。。。其实就一个素数打表,一开始就相到了,但是觉得会超时,就没敢往下想。最后没想到这么水,。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=2E5+7;
    bool prime[N]={1,0,0};
    ll arr[N];
    void inll(){
        for(ll i=2;i*i<=N;i++)
            if(!prime[i])//素数是0
                for(ll j=i+i;j<=N;j+=i)
                    prime[j]=1;//素数的倍数一定不是素数
    }
    ll su(ll x){
        ll s=0;
        ll c=sqrt(x);
        for(ll i=1;i<=c;i++){
            if(x%i==0){
                ll a=x/i;
                if(prime[i]) s++;
                if(prime[a]&&a!=i) s++;
            }
        }
        return s;
    }
    int main(){
        inll();
        prime[1]=0;
        ll n,m;
        cin>>n>>m;
        for(ll i=1;i<=n;i++){
            if(prime[i]){
                arr[su(i)]++;
            }
        }
        for(ll i=1;i<=m;i++){
            ll k;
            cin>>k;
            cout<<arr[k]<<endl;
        }
        return 0;
    }

    I

    规律题

    打表找递推式就行。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=70;
    ll a[N],b[N],c[N],d[N],e[N],f[N];
    ll ksm(ll a,ll b)
    {
        ll res=1;
        while(b){
            if(b&1) res=res*a;
            a=a*a;
            b>>=1;
        }
        return res;
    }
    
    int main(){
        a[1]=0;a[2]=1;
        b[1]=1;b[2]=1;
        c[1]=0;c[2]=0;
        for(ll i=3;i<=60;i++){
            if(i&1) a[i]=a[i-1];
            else a[i]=b[i-1]+c[i-1];
    
            if(i&1) b[i]=a[i-1]*(ll)2+(ll)1;
            else b[i]=b[i-1];
    
            if(i&1) c[i]=b[i]-(i+(ll)1)/(ll)2;
            else c[i]=c[i-1];
        }
            ll n;
            cin>>n;
            ll sum=ksm(2,n)-(ll)1;
            printf("A->B:%lld
    ",a[n]);
            printf("A->C:%lld
    ",b[n]);
            printf("B->A:%lld
    ",c[n]);
            printf("B->C:%lld
    ",a[n]);
            printf("C->A:%lld
    ",a[n]-n/(ll)2);
            printf("C->B:%lld
    ",c[n]);
            printf("SUM:%lld
    ",sum);
        return 0;
    }

    J待补

  • 相关阅读:
    使用 supervisor 管理进程
    用gunicorn+gevent启动Flask项目
    pip与apt-get
    Python计算地图上两点经纬度间的距离
    java基础学习总结——数组
    java基础学习总结——异常处理
    java基础学习总结——面向对象1
    java基础学习总结——基础语法2
    java基础学习总结——基础语法1
    java基础学习总结——java环境变量配置
  • 原文地址:https://www.cnblogs.com/Accepting/p/12288835.html
Copyright © 2011-2022 走看看