2022/8/24

1305C - Kuroni and Impossible Calculation 抽屉原理

推了三页式子还没有推出来之后去看题解直接绷不住了,一看抽屉原理就直接裂开了,确实,m只有1000,如果n>m的话那么一定有两个数是同余的那么这两个数会产生一个0,所以答案就是0,所以只需要管n<=m的情况即可,也就1000*1000的复杂度

C. Kuroni and Impossible Calculation(抽屉原理)_zjj0624的博客-CSDN博客

#include <bits/stdc++.h>
#define ll long long
#define lowbit(i) (i)&(-i)
using namespace std;
const int mod=1e9+7;
const ll inf=1e18;
const double eps=1e-8;
int qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll n,m,a[200005];
int main(){
    scanf("%lld%lld",&n,&m);
    if(n>m){
        printf("0\n");
        return 0;
    }
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    ll ans=1;
    for(int i=1;i<=n;i++)
    for(int j=i+1;j<=n;j++)
        ans=ans*abs(a[i]-a[j])%m;
    printf("%lld\n",ans);
    return 0;
}

1503A - Balance the Bits 构造

右括号一定是要小于等于左括号的,s[i]=1的时候不会影响ab中左右括号的差,但是0会影响,为了修复这个影响必然还需要一个0才可以,所以0的个数要是偶数才行,这样前一半的1都为'('后一半是')',然后s[i]==0时交替放就可以,比如奇数时a[i]='(',b[i]=')',偶数时再反过来就可以了

codeforces1503A. Balance the Bits_二分抄代码的博客-CSDN博客

#include <bits/stdc++.h>
#define ll long long
#define lowbit(i) (i)&(-i)
using namespace std;
const int mod=1e9+7;
const ll inf=1e18;
const double eps=1e-8;
int qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll t,n,a1[200005],a0[200005];
char s[200005],aa[200005],bb[200005];
int main(){
    scanf("%lld",&t);
    while(t--){
        scanf("%lld%s",&n,s+1);
        if(s[1]!='1'||s[n]!='1'){printf("NO\n");continue;}
        ll id1=0,id0=0;
        for(int i=1;i<=n;i++)
            if(s[i]=='0') a0[++id0]=i;
            else a1[++id1]=i;
        if(id0&1){printf("NO\n");continue;}
        for(int i=1;i<=id1;i++){
            if(i<=id1/2) aa[a1[i]]='(',bb[a1[i]]='(';
            else aa[a1[i]]=')',bb[a1[i]]=')';
        }
        for(int i=1;i<=id0;i++){
            if(i&1) aa[a0[i]]='(',bb[a0[i]]=')';
            else aa[a0[i]]=')',bb[a0[i]]='(';
        }
        printf("YES\n");
        for(int i=1;i<=n;i++) printf("%c",aa[i]);
        printf("\n");
        for(int i=1;i<=n;i++) printf("%c",bb[i]);
        printf("\n");
    }
    return 0;
}

1295C - Obtain The String

把每个字母的下标都存到vector中,遍历t数组如果t[i]的vector有值且有大于ind(记录遍历的最小坐标)的值那就更新ind,否则ind=t[i]vector的最小值重新开始

#include <bits/stdc++.h>
#define ll long long
#define lowbit(i) (i)&(-i)
using namespace std;
const int mod=1e9+7;
const ll inf=1e18;
const double eps=1e-8;
int qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll T,a[30];
vector<ll>v[30];
char s[100005],t[100005];
int main(){
    scanf("%lld",&T);
    while(T--){
        scanf("%s%s",s+1,t+1);
        ll n=strlen(s+1),m=strlen(t+1);
        for(int i=0;i<26;i++) v[i].clear(),a[i]=0;
        for(int i=1;i<=n;i++)
            v[s[i]-'a'].push_back(i);
        ll ans=1,ind=0;
        for(int i=1;i<=m;i++){
            if(v[t[i]-'a'].size()>a[t[i]-'a']){
                ll id=upper_bound(v[t[i]-'a'].begin(),v[t[i]-'a'].end(),ind)-v[t[i]-'a'].begin();
                //ll res=v[t[i]-'a'][a[t[i]-'a']];
                //cout<<res<<" "<<ind<<" "<<a[t[i]-'a']<<" "<<v[t[i]-'a'][a[t[i]-'a']]<<" "<<t[i]<<endl;
                //a[t[i]-'a']++;
                if(id!=v[t[i]-'a'].size()){ind=v[t[i]-'a'][id];}
                else{
                   // cout<<res<<" "<<ind<<" "<<a['s'-'a']<<endl;
                    ans++;ind=v[t[i]-'a'][0];
                   // for(int j=0;j<26;j++) a[j]=0;
                    //a[t[i]-'a']=1;
                }
            }
            else{
                if(v[t[i]-'a'].size()<=0){ans=-1;break;}
                //cout<<ind<<endl;
                ans++;ind=v[t[i]-'a'][0];
                //for(int j=0;j<26;j++) a[j]=0;
                //a[t[i]-'a']=1;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

446A - DZY Loves Sequences

这题看数据瞎搞过的,,,

求出差分数组b和b[i]的坐标c[b[i]],答案一定是在c[b[i-1]]到c[b[i+1]]-1的这段距离中,也有可能是c[b[i-1]]到c[b[i]]-1或者是c[b[i]]到c[b[i+1]]-1的这段距离中,注意下细节和满足条件就可以了

#include <bits/stdc++.h>
#define ll long long
#define lowbit(i) (i)&(-i)
using namespace std;
const int mod=1e9+7;
const ll inf=1e18;
const double eps=1e-8;
int qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll n,a[100005],c[100005],b[100005];
int main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]),b[i]=a[i]-a[i-1];
    ll cnt=0,ans=1;
    for(int i=1;i<=n;i++)
        if(b[i]<=0) c[++cnt]=i;
    c[0]=1;c[cnt+1]=n+1;b[n+1]=1e9;
    if(cnt==0){
        printf("%lld\n",n);
        return 0;
    }
    for(int i=1;i<=cnt;i++){
        //cout<<c[i]<<endl;
        if(c[i]==2&&b[c[i]+1]>0){ans=max(ans,c[i+1]-c[i-1]);continue;}
        if(a[c[i]-1]<a[c[i]+1]-1||c[i]>2&&a[c[i]-2]<a[c[i]]-1){ans=max(ans,c[i+1]-c[i-1]);}
        else ans=max(ans,max(c[i]-c[i-1]+1,c[i+1]-c[i]+1));
    }
    printf("%lld\n",ans);
    return 0;
}

其实这题最好的方法是dp

l[i]为以i结尾可以构造的最长序列,r[i]是以i开头可以构造的最长序列,

ans=max(ans,l[i-1]+1,r[i+1]+1,l[i-1]+1+r[i+1]);

#include <bits/stdc++.h>
#define ll long long
#define lowbit(i) (i)&(-i)
using namespace std;
const int mod=1e9+7;
const ll inf=1e18;
const double eps=1e-8;
int qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll n,a[100005],l[100005],r[100005];
int main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    l[1]=r[n]=1;
    for(int i=2;i<=n;i++)
        if(a[i]>a[i-1]) l[i]=l[i-1]+1;
    else l[i]=1;
    for(int i=n-1;i>=1;i--)
        if(a[i]<a[i+1]) r[i]=r[i+1]+1;
    else r[i]=1;
    ll ans=1;
    for(int i=1;i<=n;i++){
        ans=max({ans,l[i-1]+1,r[i+1]+1});
        if(a[i-1]<a[i+1]-1) ans=max(ans,l[i-1]+1+r[i+1]);
    }
    printf("%lld\n",ans);
    return 0;
}

Aeroplane chess - HDU 4405 - Virtual Judge (vjudge.net) 概率dp

首先如果第i个格子和第j个格子是有线连着的(i<j),那么第i个格子的期望就等于第j个格子的期望,否则就是i+1,i+2,,,i+6转移到i

【原创】概率DP总结 by kuangbin - kuangbin - 博客园 (cnblogs.com)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iomanip>
#include<map>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<list>
#include<stack>
#include<set>
#include<ctime>
//HDU火车头
//#include <bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-x))
using namespace std;
const int mod=1e9+7;
const ll inf=1e18;
const double eps=1e-8;
int qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll n,m;
ll vis[100005];
double dp[100005];
vector<ll>v[100005];
int main(){
    while(scanf("%lld%lld",&n,&m)){
        if(n==0&&m==0) break;
        for(int i=1;i<=n;i++) v[i].clear();
        for(int i=0;i<=n;i++) dp[i]=0;
        for(int i=0;i<=n;i++) vis[i]=0;
        for(int i=1;i<=m;i++){
        ll u,vv;
        scanf("%lld%lld",&u,&vv);
        v[vv].push_back(u);
    }
        for(int i=0;i<v[n].size();i++){
            ll j=v[n][i];
            dp[j]=0;
            vis[j]=1;
        }
        dp[n]=0;
        for(int i=n-1;i>=0;i--){
            if(!vis[i]){
                for(int j=1;j<=6;j++)
                    if(i+j<=n) dp[i]+=dp[i+j]*1.0/6;
                dp[i]+=1;
            }
            for(int j=0;j<v[i].size();j++){
                ll k=v[i][j];
                if(!vis[k]){dp[k]=dp[i];vis[k]=1;}
            }
        }
        printf("%.4f\n",dp[0]);
    }
    return 0;
}

Maze - HDU 4035 - Virtual Judge (vjudge.net) 概率dp

首先要推出节点的公式来

叶子节点:

E[i] = ki*E[1] + ei*0 + (1-ki-ei)*(E[father[i]] + 1);

非叶子节点:

E[i] = ki*E[1] + ei*0 + (1-ki-ei)/m*( E[father[i]]+1 + ∑( E[child[i]]+1 ) );

之后让

E[i] = Ai*E[1] + Bi*E[father[i]] + Ci;

然后求出A[i],B[i],C[i]的表达式来,之后E[1]就是答案

【原创】概率DP总结 by kuangbin - kuangbin - 博客园 (cnblogs.com)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iomanip>
#include<map>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<list>
#include<stack>
#include<set>
#include<ctime>
//HDU火车头
//#include <bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-x))
using namespace std;
const int mod=1e9+7;
const ll inf=1e18;
const double eps=1e-9;
int qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll t,n;
double a[10005],b[10005],c[10005],k[10005],e[10005];
vector<ll>v[10005];
bool dfs(ll u,ll fa){
    ll m=v[u].size();
    a[u]=k[u];
    b[u]=(1-k[u]-e[u])/m;
    c[u]=1-k[u]-e[u];
    double tmp=0;
    for(int i=0;i<m;i++){
        ll j=v[u][i];
        if(j==fa) continue;
        if(!dfs(j,u)) return 0;
        a[u]+=(1-k[u]-e[u])/m*a[j];
        c[u]+=(1-k[u]-e[u])/m*c[j];
        tmp+=(1-k[u]-e[u])/m*b[j];
    }
    if(fabs(tmp-1)<eps) return 0;
    a[u]/=(1-tmp);
    b[u]/=(1-tmp);
    c[u]/=(1-tmp);
    return 1;
}
int main(){
    scanf("%lld",&t);
    ll cnt=0;
    while(t--){
        scanf("%lld",&n);
        for(int i=1;i<=n;i++) v[i].clear();
        for(int i=1;i<n;i++){
            ll u,vv;
            scanf("%lld%lld",&u,&vv);
            v[u].push_back(vv);
            v[vv].push_back(u);
        }
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",&k[i],&e[i]);
            k[i]/=100;e[i]/=100;
        }
        printf("Case %d: ",++cnt);
        if(dfs(1,-1)&&fabs(1-a[1])>eps){
            printf("%.6lf\n",c[1]/(1-a[1]));
        }
        else printf("impossible\n");
    }
    return 0;
}

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...