第45届ICPC 亚洲区域赛上海:部分题解(BCDEGHIM)

金了,开心

链接:https://ac.nowcoder.com/acm/contest/9925#question

在这里插入图片描述

B Mine Sweeper II【构造】

队友写的

#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--)
typedef long long ll;
typedef double db;
const int MOD = 1e9+7;
const int N = 2e3+5;
struct Node_
{
    int x;
    db dis;
};
bool operator < (Node_ x,Node_ y)
{
    return x.dis>y.dis;
}
string a[N],b[N];
int n,m;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for (int i=1;i<=n;++i) cin>>a[i];
    for (int i=1;i<=n;++i) cin>>b[i];
    int cnt=0;
    for (int i=1;i<=n;++i)
    {
        for (int j=0;j<m;++j)
            cnt+=(a[i][j]!=b[i][j]);
    }
    if (cnt*2<=n*m)
    {
        for (int i=1;i<=n;++i) cout<<a[i]<<endl;
    }else
    {
        for (int i=1;i<=n;++i)
        {
            for (int j=0;j<m;++j) a[i][j]=(a[i][j]=='.') ? 'X' : '.';
            cout<<a[i]<<endl;
        }
    }
    return 0;
}

C Sum of Log【数位dp】

类似数位dp,枚举i的取值,默认 i > j i>j i>j,dfs过程中保存 i i i中最高位的位置。

#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--)
typedef long long LL;
typedef long long ll;
typedef long double LD;
#define pii pair<int,int>
#define pill pair<int,int>
#define fi first
#define se second
#define pb push_back

LL read(){
    LL a;
    scanf("%lld",&a);
    return a;
}
#define rd read()

const LL mod=1e9+7;
LL p3[100];

LL x,y;
int xb,yb;
bool vis[33][2][2][33];
LL ans[33][2][2][33];
LL dfs(int b,bool f1,bool f2,int mb){
    if(b==-1){
        if(mb==-1)return 0;
        return 1ll*(mb+1)%mod;
    }
    if(f1&&f2&&mb!=-1){
        return p3[b+1]*(mb+1)%mod;
    }
    if(vis[b][f1][f2][mb])
        return ans[b][f1][f2][mb];
    vis[b][f1][f2][mb]=1;

    LL sum=0;
    // 0 0
    bool _f1=f1,_f2=f2;
    if(x&(1<<b))_f1=1;
    if(y&(1<<b))_f2=1;
    sum+=dfs(b-1,_f1,_f2,mb);
    // 0 1
    _f1=f1;
    if(x&(1<<b))_f1=1;
    if(mb!=-1&&(f2||(y&(1<<b))))
        sum+=dfs(b-1,_f1,f2,mb);
    // 1 0
    _f2=f2;
    if(y&(1<<b))_f2=1;
    int _mb=mb;
    if(mb==-1)_mb=b;
    if(f1||(x&(1<<b)))
        sum+=dfs(b-1,f1,_f2,_mb);
    return ans[b][f1][f2][mb]=sum%mod;
}
// i>j
LL deal(int xx,int yy){
    if(xx==0)return 0;
    memset(vis,0,sizeof vis);
    x=xx,y=yy;
    xb=-1,yb=-1;

    rep(i,0,30){
        if(x&(1<<i))xb=i;
        if(y&(1<<i))yb=i;
    }
    return dfs(max(xb,yb),0,0,-1);
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    p3[0]=1;
    rep(i,1,40)p3[i]=p3[i-1]*3%mod;
    int t;
    cin>>t;
    while(t--){
        int xx,yy;
        cin>>xx>>yy;
        printf("%lld\n",(deal(xx,yy)+deal(yy,xx))%(mod));
    }
}

D Walker【想法 数学】

将区间分成ABC3段
在这里插入图片描述

情况:

  • 第一个人A,第二个人BC
  • 第一个人AB,第二个人C
  • 第一个人ABC
  • 第二个人ABC
  • 第一个人BC,第二个人AC
  • 一起管B
    • 设第一个人管辖的区域长度为X,最后情况一定是双方同时走完自己的区域,解方程即可

最恶心的情况:第一个人BC,第二个人AC

#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--)
typedef long long LL;
typedef long long ll;
typedef long double LD;
#define pii pair<int,int>
#define pill pair<int,int>
#define fi first
#define se second
#define pb push_back

LL read(){
    LL a;
    scanf("%lld",&a);
    return a;
}
#define rd read()

LD n,p1,v1,p2,v2;

int main(){
    int t=rd;
    while(t--){
        double tmp[10];
        rep(i,1,5)scanf("%lf",&tmp[i]);
        int ar=0;
        n=tmp[++ar];
        p1=tmp[++ar];
        v1=tmp[++ar];
        p2=tmp[++ar];
        v2=tmp[++ar];
        //scanf("%lf%lf%lf%lf%lf",&n,&p1,&v1,&p2,&v2);
        if(p1>p2){
            swap(p1,p2);
            swap(v1,v2);
        }
        LD ans=1e18;
        ans=min((n+p1)/v1,(n+p2)/v2);
        ans=min(ans,min((n+n-p1)/v1,(n+n-p2)/v2));
        ans=min(ans,min( max(p1/v1,(p2-p1+2*(n-p2))/v2) ,max(p1/v1,(2*(p2-p1)+n-p2)/v2)  ));
        ans=min(ans,min( max((n-p2)/v2,(p2+p1)/v1) , max((n-p2)/v2,(p2+p2-p1)/v1) ));
        ans=min(ans,max((n-p1)/v1,(p2)/v2));

        LD x=(v1*n+v1*p2-v2*p1)/(v2+2*v1);
        if(x>=p1&&x<=p2){
            assert(fabs((x+p1)/v1-(n-x+p2-x)/v2)<1e-6);
            ans=min(ans,(x+p1)/v1);
        }

        x=(2*v1*n-v1*p2-p1*v2)/(v2+v1);
        if(x>=p1&&x<=p2){
            assert(fabs((x+p1)/v1-(n-x+n-p2)/v2)<1e-6);
            ans=min(ans,(x+p1)/v1);
        }

        x=(2*n*v1-p2*v1+p1*v2)/(2*v2+v1);
        if(x>=p1&&x<=p2){
            assert(fabs((x+x-p1)/v1-(n-x+n-p2)/v2)<1e-6);
            ans=min(ans,(x+x-p1)/v1);
        }

        x=(n*v1+p2*v1+p1*v2)/(2*v2+2*v1);
        if(x>=p1&&x<=p2){
            assert(fabs((x+x-p1)/v1-(n-x+p2-x)/v2)<1e-6);
            ans=min(ans,(x+x-p1)/v1);
        }


        printf("%.10f\n",(double)ans);
    }

}

E The Journey of Geor Autumn【找规律 dp】

队友写的

#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--)
typedef long long LL;
typedef long long ll;
typedef long double LD;
#define pii pair<int,int>
#define pill pair<int,int>
#define fi first
#define se second
#define pb push_back
const int MAXN = 1e7+4;
const int MOD=998244353;
ll qpow(ll a,ll b)
{
    a%=MOD;
    ll ret=1;
    while(b)
    {
        if(b&1)ret=ret*a%MOD;
        a=a*a%MOD;
        b>>=1;
    }
    return ret;
}
ll dp[MAXN];
ll fac[MAXN],invfac[MAXN];
void init()
{
    fac[0]=1;
    for(int i=1;i<MAXN;i++)fac[i]=fac[i-1]*i%MOD;
    invfac[MAXN-1]=qpow(fac[MAXN-1],MOD-2);
    for(int i=MAXN-2;i>=0;i--)invfac[i]=invfac[i+1]*(i+1)%MOD;
}
void work()
{
    int n,k;
    scanf("%d%d",&n,&k);
   // swap(n,k);
//    dp[0][0]=1;
//    for(int i=1;i<=n;i++)
//    {
//        for(int j=1;j<=n;j++)
//        {
//            dp[i][j]=dp[i-1][j]*(j-i+1);
//            for(int x=1;x<=k&&x<=j;x++)dp[i][j]+=dp[i-1][j-x];
//            printf("%8lld ",dp[i][j]);
//        }
//        printf("\n");
//    }
//
    dp[0]=1;
    for(int i=1;i<=n;i++)
    {
        if(i<=k)dp[i]=dp[i-1]*i%MOD;
        else dp[i]=(dp[i-1]*i%MOD-dp[i-k-1]*fac[i-1]%MOD*invfac[i-k-1]%MOD+MOD)%MOD;
        dp[i]=(dp[i]+MOD)%MOD;
 //       printf("%lld\n",dp[i]);
    }
    printf("%lld\n",dp[n]);

}

int main(){
    init();
   // for(int i=1;i<=5;i++)printf("%lld %lld\n",fac[i],invfac[i]);
   // int T;scanf("%d",&T);for(int cas=1;cas<=T;cas++)
    {
        work();
    }

}

G Fibonacci

队友写的

#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--)
typedef long long LL;
typedef long long ll;
typedef long double LD;
#define pii pair<int,int>
#define pill pair<int,int>
#define fi first
#define se second
#define pb push_back

LL read(){
    LL a;
    scanf("%lld",&a);
    return a;
}
#define rd read()

int main(){
    LL n=rd;
    if(n==1){
        puts("0");
        return 0;
    }
    LL ans=n*(n-1)/2;
    n=n-(n/3);
    ans-=n*(n-1)/2;
    printf("%lld\n",ans);
}

H Rice Arrangement【想法】

分析后得到菜和人一定是顺位的关系:定下一个后其他的接下去就行了。

所以枚举第一个位置,可以用滑窗得到此时的答案:

例如差值为 − 9 , − 5 , − 1 , 0 -9,-5,-1,0 9,5,1,0,n是12

  • − 9 , − 5 , − 1 , 0 → a n s = 9 -9,-5,-1,0\to ans=9 9,5,1,0ans=9
  • − 5 , − 1 , 0 , 3 → a n s = 11 -5,-1,0,3\to ans=11 5,1,0,3ans=11
  • − 1 , 0 , 3 , 7 → a n s = 9 -1,0,3,7\to ans=9 1,0,3,7ans=9
  • ……
#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--)
typedef long long LL;
typedef long long ll;
typedef long double LD;
#define pii pair<int,int>
#define pill pair<int,int>
#define fi first
#define se second
#define pb push_back

const LL mod=998244353;


LL a[5009],b[5009];
LL c[10009];

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;cin>>t;
    while(t--){
        int n,k;
        cin>>n>>k;
        rep(i,1,k)cin>>a[i];
        sort(a+1,a+1+k);
        rep(i,1,k)cin>>b[i];
        sort(b+1,b+1+k);
        LL ans=1e18;
        rep(f,0,k-1){
            rep(i,1,k){
                c[i]=a[i]-b[(i+f-1)%k+1];
                if(c[i]>0){
                    c[i]-=n;
                }
            }
            sort(c+1,c+1+k);
            int l=1;
            rep(i,1,k+1){
                if(c[l]<=0&&c[l+k-1]>=0){
                    ans=min(ans,min(c[l+k-1]-c[l]-c[l],c[l+k-1]+c[l+k-1]-c[l]));
                }
                else if(c[l]<=0&&c[l+k-1]<=0){
                    ans=min(ans,-c[l]);
                }
                else{
                    ans=min(ans,c[l+k-1]);
                }
                c[l+k]=c[l]+n;
                l++;
            }
        }
        cout<<ans<<endl;
    }
}
/*
111
1000 1
100
900
*/

I Sky Garden

队友写的

#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--)
typedef long long ll;
typedef double db;
const int MOD = 1e9+7;
const int N = 1e5+5;
const db pi = acos(-1);
int n,m;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    if (m==1)
    {
        ll ans=0;
        for (int i=-n;i<=n;++i)
        if (i)
        {
            for (int j=i+1;j<=n;++j)
            if (j)
            {
                ans+=j-i;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    db ans=0;
    for (int k=-m;k<m;++k)
    {
        db xita=pi*abs(k)/m;
        xita=min(xita-2,(db)0);
        //cout<<"k="<<k<<' '<<xita<<endl;
        for (int r1=1;r1<=n;++r1)
        {
            for (int r2=0;r2<r1;++r2)
            {
                if (r2==0 && k!=0) continue;
                ans+=((db)r1+r2+xita*r2);
            }
            ans+=((db)r1+r1+xita*r1)/2;
        }
    }
    ans*=(2*m);
    printf("%.10f\n",ans);
    return 0;
}

M Gitignore

队友写的

#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--)
typedef long long ll;
typedef double db;
const int MOD = 1e9+7;
const int N = 1e5+5;
struct Node_
{
    int x;
    db dis;
};
bool operator < (Node_ x,Node_ y)
{
    return x.dis>y.dis;
}
string st;
int dp[N],f2[N];
int n,m;
struct ACAM
{
    struct Node
    {
        int nxt[30];
        int c;
    }node[N];
    int rt,nodecnt;
    void init()
    {
        for (int i=1;i<=nodecnt;++i)
        {
            memset(node[i].nxt,0,sizeof(node[i].nxt));
            node[i].c=0;
        }
        rt=nodecnt=1;
    }
    int extend(int p,int c)
    {
        if (node[p].nxt[c]) return node[p].nxt[c];
        int cur=++nodecnt;
        node[p].nxt[c]=cur;
        return cur;
    }
    void getdp(int now,int lst)
    {
        dp[now]=0;
        f2[now]=0;
        for (int i=0;i<=26;++i)
        if (node[now].nxt[i])
        {
            getdp(node[now].nxt[i],i);
            dp[now]+=dp[node[now].nxt[i]];
            f2[now]|=f2[node[now].nxt[i]];
        }
        if (node[now].c>0)
        {
            dp[now]+=(node[now].c==1);
            f2[now]|=(node[now].c==2);
        }
        if (!f2[now] && now!=rt && lst==0) dp[now]=min(dp[now],1);
    }
}ac;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int T;cin>>T;
    while (T--)
    {
        ac.init();
        cin>>n>>m;
        for (int i=1;i<=n;++i)
        {
            cin>>st;
            int p=ac.rt;
            for (int i=0;i<st.size();++i)
            {
                int ch;if (st[i]=='/') ch=0;else ch=st[i]-'a'+1;
                p=ac.extend(p,ch);
            }
            ac.node[p].c=1;
        }
        for (int i=1;i<=m;++i)
        {
            cin>>st;
            int p=ac.rt;
            for (int i=0;i<st.size();++i)
            {
                int ch;if (st[i]=='/') ch=0;else ch=st[i]-'a'+1;
                p=ac.extend(p,ch);
            }
            ac.node[p].c=2;
        }
        ac.getdp(ac.rt,1);
        //for (int i=1;i<=ac.nodecnt;++i) cout<<dp[i]<<' ';cout<<endl;
        cout<<dp[ac.rt]<<endl;
    }
    return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值