zoukankan      html  css  js  c++  java
  • 【题解】2020 年电子科技大学 ACM-ICPC 暑假前集训

    比赛地址

    A - 第一章:小试牛刀

    KMP板子

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int N=1e6+1;
    int i,j,ls,lp,nxt[N];
    string s,p;
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>s>>p;
        ls=s.length();
        lp=p.length();
        i=0,j=-1;
        nxt[0]=-1;
        while(i<lp)
            if(j<0||p[i]==p[j])
                nxt[++i]=++j;
            else
                j=nxt[j];
        i=0,j=0;
        while (i<ls){
            if (j<0||s[i]==p[j])
                i++,j++;
            else
                j=nxt[j];
            if (j==lp){
                cout<<i-lp+1<<" ";
                j=nxt[j];
            }
        }
    }
    

    B - 第二章:北境之王的现身

    (f[i][j])表示前(i)个字符组成的串匹配到KMP自动机的(j)号节点的方案数

    每一步对答案的贡献就是(f[i][n]*sum^n_{i+1}|t[i]|)

    #include <cstdio>
    #include <cstring>
    typedef long long ll;
    const ll N=1e3+1,M=26,T=2e6+2,K=1e9+7;
    char s[N],t[M];
    ll ls,lt[T],f[N],g[N],tr[N][M],cnt[N],fail[N],m,ans,bak[T];
    void build(char *s){
        ls=strlen(s);
        for (ll i=0;i<ls;i++)
            tr[i][s[i]-'a']=i+1;
        for (ll i=1;i<=ls;i++)
            for (ll j=0;j<M;j++)
                if (tr[i][j])
                    fail[tr[i][j]]=tr[fail[i]][j];
                else
                    tr[i][j]=tr[fail[i]][j];
    }
    int main(){
        scanf("%s",s);
        build(s);
        scanf("%lld",&m);
        for (ll i=1;i<=m;i++) scanf("%lld",&lt[i]);
        bak[m+1]=1;
        for (ll i=m;i>=1;i--) bak[i]=bak[i+1]*lt[i]%K;
        f[0]=1;
        for (ll i=1;i<=m;i++){
            memset(g,0,sizeof(g));
            scanf("%s",t);
            for (ll j=0;j<lt[i];j++){
                for (ll k=0;k<=ls;k++)
                    g[tr[k][t[j]-'a']]=(g[tr[k][t[j]-'a']]+f[k])%K;
            }
            ans=(ans+g[ls]*bak[i+1]%K)%K;
            memcpy(f,g,sizeof(f));
        }
        printf("%lld",ans);
    }
    

    C - 第三章:向监狱进发

    每个串的所有前缀都可以由(fail)指针得到,所以可以由(fail)指针构建一个树,再按拓扑序(dp)即可

    (f[i][j])表示拓扑序前(i)个点构成了(j)个集合的方案数,(w(i))表示前(i-1)个点中有多少个第(i)点的祖先,可以用树状数组维护

    (f[i][j]=f[i-1][j]*(j-w(i))+f[i-1][j-1])

    #include <iostream>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    const ll N=1e5+10,M=26,K=1e9+7;
    ll tr[N][26],tot,fail[N];
    ll k,m,q,n,a,b,sz,in[N],out[N],t[N],f[N][301],tmp[N],head[N];
    string s[N];
    vector<int> pos[N];
    struct E{
        ll next,to;
    }e[N];
    void add(ll x,ll v){
        for (ll i=x;i<=tot;i+=i&-i) t[i]+=v;
    }
    ll query(ll x){
        ll ans=0;
        for (ll i=x;i;i-=i&-i) ans+=t[i];
        return ans;
    }
    void insert(ll a,ll b){
        sz++;
        e[sz].next=head[a];
        head[a]=sz;
        e[sz].to=b;
    }
    ll inserts(char *s,ll id){
        ll u = 0;
        pos[id].push_back(0);
        for (ll i = 0; s[i]; i++) {
            if (!tr[u][s[i]-'a'])
                tr[u][s[i]-'a']=++tot;
            u=tr[u][s[i]-'a'];
            pos[id].push_back(u);
        }
        return u;
    }
    queue<int> que;
    void dfs(ll x){
        in[x]=++tot;
        for (ll i=head[x];i;i=e[i].next){
            ll u=e[i].to;
            dfs(u);
        }
        out[in[x]]=tot;
    }
    void build(){
        for (ll i=0;i<M;i++)
            if (tr[0][i])
                que.push(tr[0][i]);
        while (!que.empty()){
            ll u = que.front();
            que.pop();
            for (ll i = 0; i < 26; i++) {
                if (tr[u][i]){
                    fail[tr[u][i]]=tr[fail[u]][i];
                    que.push(tr[u][i]);
                }else{
                    tr[u][i]=tr[fail[u]][i];
                }
            }
        }
        for (ll i=1;i<=tot;i++)
            insert(fail[i],i);
        tot=-1;
        dfs(0);
    }
    ll solve(){
        f[0][0]=1;
        for (ll i=1;i<=k;i++){
            ll pre=query(tmp[i]);
            for (ll j=1;j<=m;j++)
                f[i][j]=(f[i-1][j-1]+f[i-1][j]*((j-pre>0)?(j-pre):0))%K;
            add(tmp[i],1);
            add(out[tmp[i]]+1,-1);
        }
        for (ll i=1;i<=k;i++){
            add(tmp[i],-1);
            add(out[tmp[i]]+1,1);
        }
        return f[k][m];
    }
    int main(){
        cin>>n>>q;
        for (ll i=1;i<=n;i++){
            cin>>s[i];
            inserts((char *)s[i].c_str(),i);
        }
        build();
        for (ll i=1;i<=q;i++){
            cin>>k>>m;
            for (ll j=1;j<=k;j++){
                cin>>a>>b;
                tmp[j]=in[pos[a][b]];
            }
            sort(tmp+1,tmp+k+1);
            cout<<solve()<<endl;
        }
    }
    

    D - 第四章:不要停下来啊!!!!

    数位DP

    (s)的所有后缀插入到AC自动机中

    (f[i][j])表示前(i)位组成的串匹配到AC自动机的第(j)个节点

    然后对答案的贡献和(B)题差不多,也要乘一下后缀积

    最后上下界的答案做差即可

    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    typedef long long ll;
    const ll N=500+10,M=10,K=1e9+7;
    ll q,d,tr[N*N][M],fail[N*N],dep[N*N],f[N*N],g[N*N],tot,pd;
    char s[N],a[N],b[N];
    queue<int> que;
    void insert(char *s){
        ll u=0;
        for (ll i=0;s[i];i++) {
            if (!tr[u][s[i]-'0'])
                tr[u][s[i]-'0']=++tot;
            u=tr[u][s[i]-'0'];
            dep[u]=i+1;
        }
    }
    void build(){
        for (ll i=0;i<M;i++)
            if (tr[0][i])
                que.push(tr[0][i]);
        while (!que.empty()){
            ll u = que.front();
            que.pop();
            for (ll i=0;i<M;i++) {
                if (tr[u][i]){
                    fail[tr[u][i]]=tr[fail[u]][i];
                    que.push(tr[u][i]);
                }else{
                    tr[u][i]=tr[fail[u]][i];
                }
            }
        }
    }
    ll solve(char *s,ll d){
        pd=0;
        ll ans=0;
        memset(f,0,sizeof(f));
        for (ll i=0;s[i];i++){
            ans=(ans*10)%K;
            memset(g,0,sizeof(g));
            for (ll j=0;j<s[i]-'0';j++)
                if (i!=0||j!=0){
                    if (dep[pd]!=d)
                        g[tr[pd][j]]=(g[tr[pd][j]]+1)%K;
                    else
                        ans=(ans+1)%K;
                }
            for (ll j=0;j<=tot;j++)
                for (ll k=0;k<M;k++)
                    g[tr[j][k]]=(g[tr[j][k]]+f[j])%K;
            for (ll j=0;j<=tot;j++)
                if (dep[j]==d){
                    ans=(ans+g[j])%K;
                    g[j]=0;
                }
            memcpy(f,g,sizeof(f));
            if (dep[pd]!=d) pd=tr[pd][s[i]-'0'];
        }
        return ans;
    }
    int main(){
        scanf("%s",s);
        for (ll i=0;s[i];i++) insert(s+i);
        build();
        scanf("%lld",&q);
        for (ll i=1;i<=q;i++){
            scanf("%s
    %s
    %lld",a,b,&d);
            ll ans=solve(b,d);
            ans=(ans+(dep[pd]==d))%K;
            ans=(K+ans-solve(a,d))%K;
            printf("%lld
    ",ans);
        }
    }
    

    E - 第五章:与熊共斗

    F - 第六章:最终决战

    G - 一行超人

    手写自动机

    #include <iostream>
    #include <map>
    #include <vector>
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    typedef long long ll;
    const ll K=1e9;
    struct INS{
        char op;
        string a,b,c,d;
        ll jmp;
    }tmp;
    map<string,ll> var;
    vector<INS> ins;
    vector<ll> jmp,in,out,ans;
    void print(INS i){
        printf("%c	%s	%s	%s	%s	%lld
    ",i.op,
        i.a.c_str(),i.b.c_str(),i.c.c_str(),i.d.c_str(),i.jmp);
    }
    void run(){
        ll t=0,ip=0,inip=0;
        while(ip!=ins.size()){
            INS i=ins[ip];
            if (t==100000&&i.op!='j'){printf("Time Limit Exceeded");return;}
            if (i.op=='n'){
                t++;
                if (var.count(i.a)){printf("Runtime Error");return;}
                var.insert(make_pair(i.a,0));
                ip++;
            }
            if (i.op=='d'){
                t++;
                if (!var.count(i.a)){printf("Runtime Error");return;}
                var.erase(i.a);
                ip++;
            }
            if (i.op=='r'){
                t++;
                if (!var.count(i.a)){printf("Runtime Error");return;}
                if (inip!=in.size()){
                    var[i.a]=in[inip];
                    inip++;
                }
                ip++;
            }
            if (i.op=='w'){
                t++;
                if (!var.count(i.a)){printf("Runtime Error");return;}
                ans.push_back(var[i.a]);
                ip++;
            }
            if (i.op=='='){
                t++;
                ll a,b,c;
                if (!var.count(i.a)){printf("Runtime Error");return;}
                if ('a'<=i.b[0]&&i.b[0]<='z'){
                    if (!var.count(i.b)){printf("Runtime Error");return;}
                    b=var[i.b];
                }else{
                    b=atoi(i.b.c_str());
                }
                if ('a'<=i.c[0]&&i.c[0]<='z'){
                    if (!var.count(i.c)){printf("Runtime Error");return;}
                    c=var[i.c];
                }else{
                    c=atoi(i.c.c_str());
                }
                if (i.d=="+") a=(b+c)%K;
                if (i.d=="-") a=(b-c+K)%K;
                if (i.d=="*") a=(b*c)%K;
                if (i.d=="/"){
                    if (c==0){printf("Runtime Error");return;}
                    a=(b/c);
                }
                if (i.d=="%"){
                    if (c==0){printf("Runtime Error");return;}
                    a=(b%c);
                }
                var[i.a]=a;
                ip++;
            }
            if (i.op=='i'||i.op=='l'){
                t++;
                ll a,b,c;
                if ('a'<=i.a[0]&&i.a[0]<='z'){
                    if (!var.count(i.a)){printf("Runtime Error");return;}
                    a=var[i.a];
                }else{
                    a=atoi(i.a.c_str());
                }
                if ('a'<=i.b[0]&&i.b[0]<='z'){
                    if (!var.count(i.b)){printf("Runtime Error");return;}
                    b=var[i.b];
                }else{
                    b=atoi(i.b.c_str());
                }
                if (i.c=="<") c=(a<b);
                if (i.c=="<=") c=(a<=b);
                if (i.c==">") c=(a>b);
                if (i.c==">=") c=(a>=b);
                if (i.c=="==") c=(a==b);
                if (i.c=="!=") c=(a!=b);
                if (!c){
                    ip=i.jmp;
                }else{
                    ip++;
                }
            }
            if (i.op=='j'){
                if (ins[i.jmp].op=='l'){
                    ip=i.jmp;
                }else{
                    ip++;
                }
            }
        }
        ll len=out.size(),ac=0;
        if (out.size()==ans.size()){
            ac=1;
            for (ll i=0;i<len;i++)
                if (out[i]!=ans[i]) ac=0;
        }
        if (ac)
            printf("Accepted");
        else
            printf("Wrong Answer");
        
    }
    int main(){
        string s,t;
        char ch=' ';
        while(1){
            tmp.a=tmp.b=tmp.c=tmp.d="";tmp.jmp=0;
            while(ch==' '){ch=getchar();}s.clear();
            if (ch=='
    '){
                ch=getchar();
                if (!jmp.empty()) break;
                while(1){
                    while(ch==' '){ch=getchar();}ll n=0;
                    if (ch=='
    ') break;
                    while('0'<=ch&&ch<='9'){n=n*10+ch-'0';ch=getchar();}
                    in.push_back(n);
                }
                ch=getchar();
                while(1){
                    while(ch==' '){ch=getchar();}ll n=0;
                    if (ch=='
    '||ch==EOF) break;
                    while('0'<=ch&&ch<='9'){n=n*10+ch-'0';ch=getchar();}
                    out.push_back(n);
                }
                run();
                return 0;
            }
            if (ch=='}'){
                ch=getchar();
                if (jmp.empty()) break;
                ins[jmp.back()].jmp=ins.size()+1;
                tmp.op='j';
                tmp.jmp=jmp.back();
                ins.push_back(tmp);
                jmp.pop_back();
                continue;
            }
            while('a'<=ch&&ch<='z'){s=s+ch;ch=getchar();}
            if (s=="new"||s=="delete"||s=="read"||s=="write"){
                tmp.op=s[0];
                while(ch==' '){ch=getchar();}t.clear();
                while('a'<=ch&&ch<='z'){t=t+ch;ch=getchar();}
                ll len=t.length();if (len<1||len>10) break;
                if (t=="new"||t=="delete"||t=="read"||t=="write"||t=="if"||t=="while") break;
                while(ch==' '){ch=getchar();}if (ch!=';') break;ch=getchar();
                tmp.a=t;
                ins.push_back(tmp);
                continue;
            }
            if (s=="if"||s=="while"){
                tmp.op=s[0];
                if (tmp.op=='w') tmp.op='l';
                while(ch==' '){ch=getchar();}if (ch!='(') break;ch=getchar();
                while(ch==' '){ch=getchar();}t.clear();
                if ('a'<=ch&&ch<='z'){
                    t=t+ch;ch=getchar();
                    while('a'<=ch&&ch<='z'){t=t+ch;ch=getchar();}
                    ll len=t.length();if (len<1||len>10) break;
                    if (t=="new"||t=="delete"||t=="read"||t=="write"||t=="if"||t=="while") break;
                }else if ('0'<=ch&&ch<='9'){
                    t=t+ch;ch=getchar();
                    while('0'<=ch&&ch<='9'){t=t+ch;ch=getchar();}
                    ll len=t.length();if (len<1||len>9||len>=2&&t[0]=='0') break;
                }else break;
                tmp.a=t;
                while(ch==' '){ch=getchar();}t.clear();
                while(ch=='<'||ch=='>'||ch=='!'||ch=='='){t=t+ch;ch=getchar();}
                if (t!="<"&&t!="<="&&t!=">"&&t!=">="&&t!="=="&&t!="!=") break;
                tmp.c=t;
                while(ch==' '){ch=getchar();}t.clear();
                if ('a'<=ch&&ch<='z'){
                    t=t+ch;ch=getchar();
                    while('a'<=ch&&ch<='z'){t=t+ch;ch=getchar();}
                    ll len=t.length();if (len<1||len>10) break;
                    if (t=="new"||t=="delete"||t=="read"||t=="write"||t=="if"||t=="while") break;
                }else if ('0'<=ch&&ch<='9'){
                    t=t+ch;ch=getchar();
                    while('0'<=ch&&ch<='9'){t=t+ch;ch=getchar();}
                    ll len=t.length();if (len<1||len>9||len>=2&&t[0]=='0') break;
                }else break;
                tmp.b=t;
                while(ch==' '){ch=getchar();}if (ch!=')') break;ch=getchar();
                while(ch==' '){ch=getchar();}if (ch!='{') break;ch=getchar();
                jmp.push_back(ins.size());
                ins.push_back(tmp);
                continue;
            }
            ll len=s.length();if (len<1||len>10) break;
            while(ch==' '){ch=getchar();}if (ch!='=') break;ch=getchar();
            while(ch==' '){ch=getchar();}t.clear();
                if ('a'<=ch&&ch<='z'){
                    t=t+ch;ch=getchar();
                    while('a'<=ch&&ch<='z'){t=t+ch;ch=getchar();}
                    ll len=t.length();if (len<1||len>10) break;
                    if (t=="new"||t=="delete"||t=="read"||t=="write"||t=="if"||t=="while") break;
                }else if ('0'<=ch&&ch<='9'){
                    t=t+ch;ch=getchar();
                    while('0'<=ch&&ch<='9'){t=t+ch;ch=getchar();}
                    ll len=t.length();if (len<1||len>9||len>=2&&t[0]=='0') break;
                }else break;
            tmp.op='=',tmp.a=s,tmp.b=t;
            while(ch==' '){ch=getchar();}if (ch==';'){ch=getchar();
                tmp.c="0",tmp.d="+";
                ins.push_back(tmp);
                continue;
            }
            if (ch!='+'&&ch!='-'&&ch!='*'&&ch!='/'&&ch!='%') break;tmp.d=ch;ch=getchar();
            while(ch==' '){ch=getchar();}t.clear();
                if ('a'<=ch&&ch<='z'){
                    t=t+ch;ch=getchar();
                    while('a'<=ch&&ch<='z'){t=t+ch;ch=getchar();}
                    ll len=t.length();if (len<1||len>10) break;
                    if (t=="new"||t=="delete"||t=="read"||t=="write"||t=="if"||t=="while") break;
                }else if ('0'<=ch&&ch<='9'){
                    t=t+ch;ch=getchar();
                    while('0'<=ch&&ch<='9'){t=t+ch;ch=getchar();}
                    ll len=t.length();if (len<1||len>9||len>=2&&t[0]=='0') break;
                }else break;
            tmp.c=t;
            while(ch==' '){ch=getchar();}if (ch!=';') break;ch=getchar();
            ins.push_back(tmp);
        }
        printf("Compile Error");
    }
    

    Q - 给小马染色

    把原问题拆成两半(f1)(f2),再合并起来

    (f[s])表示黑马集合为(s)的方案数

    然后对于(f1)中每个局面(s)只需要找出(f2)中与之不冲突的的所有局面(t)进行组合即可

    然后这些局面(t)有包含关系,所以求(m)维的前缀和即可

    注意这里要用(m)次一位前缀和来计算,不能用容斥原理计算

    位移写成1<<a是错的,要改成1LL<<a才可以

    #include <cstdio>
    typedef long long ll;
    const ll N=40;
    ll n,m,p,q,a,b,d[N],f[(1<<20)],g[(1<<20)],ans,t;
    int main(){
        scanf("%lld%lld",&n,&m);
        p=n/2,q=n-p;
        for (ll i=1;i<=m;i++){
            scanf("%lld%lld",&a,&b);
            a--,b--;
            d[a]|=1LL<<b,d[b]|=1LL<<a;
        }
        f[0]=1;
        for (ll i=0;i<(1<<p);i++)
            for (ll j=0;j<p;j++)
                if (!(i&(1<<j))&&!(d[j]&i))
                    f[i|(1<<j)]|=f[i];
        for (ll i=0;i<p;i++)
            for (ll j=0;j<(1<<p);j++)
                if (!(j&(1<<i)))
                    f[j|(1<<i)]+=f[j];
        g[0]=1;
        for (ll i=0;i<(1<<q);i++)
            for (ll j=0;j<q;j++)
                if (!(i&(1<<j))&&!((d[j+p]>>p)&i))
                    g[i|(1<<j)]|=g[i];
        for (ll i=0;i<(1<<q);i++){
            t=0;
            for (ll j=0;j<q;j++)
                if (i&(1<<j))
                    t|=d[j+p]&((1<<p)-1);
            ans+=g[i]*f[(1<<p)-1-t];
        }
        printf("%lld",ans);
    }
    

    R - 小马的强迫症

    搜索

    选择一个区间肯定不能移到原来的位置

    而且如果只移动一个元素(x)要么左面是(x-1)要么右面是(x+1)

    把重复和无用的分治剪掉每步就只有84种可能

    每一步最多使不连续的段减去3

    所以再加个估价函数剪枝即可

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int n,f[9][9],ans;
    void dfs(int d){
        int cnt=0;
        for (int i=0;i<=n-2;i++)
            if (f[d][i]>f[d][i+1])
                cnt++;
        if (cnt==0){
            ans=min(d,ans);
            return;
        }
        if (d+(cnt+2)/3>=ans)
            return;
        for (int i=0;i<=n-2;i++)
            for (int j=i;j<=n-2;j++){
                for (int k=j+1;k<=n-1;k++)
                {
                    if (k==j+1&&(
                        f[d][k]==1&&i!=0||
                        f[d][k]!=1&&f[d][i-1]!=f[d][k]-1&&f[d][i]!=f[d][k]+1))
                        continue;
                    if (i==j&&(
                        f[d][i]==n&&k!=n-1||
                        f[d][i]!=n&&f[d][k]!=f[d][i]-1&&f[d][k+1]!=f[d][i]+1))
                        continue;
                    int pt=0;
                    for (int t=0;t<=i-1;t++) f[d+1][pt++]=f[d][t];
                    for (int t=j+1;t<=k;t++) f[d+1][pt++]=f[d][t];
                    for (int t=i;t<=j;t++) f[d+1][pt++]=f[d][t];
                    for (int t=k+1;t<=n-1;t++) f[d+1][pt++]=f[d][t];
                    dfs(d+1);
                }
            }
    }
    int main(){
        scanf("%d",&n);
        ans=n-1;
        for (int i=0;i<n;i++) scanf("%d",&f[0][i]);
        dfs(0);
        printf("%d",ans);
    }
    

    S - 小马跑得快

    和斗地主差不多

    优先出不同牌的组合

    最后贪心打完所有相同牌的组合

    直接搜索即可

    #include <cstdio>
    #include <cstring>
    #include <climits>
    const int N=13;
    int t,n,c[N+2],ans;
    char s[]="A234567891JQK",name[3];
    void dfs(int d);
    int calc(){
        int ans=0;
        for (int i=0;i<N;i++) ans+=(3+c[i])/4;
        return ans;
    }
    void multi(int d,int i,int len,int cnt){
        int pt=i;
        while(c[pt%N]>=cnt&&pt<=N) pt++;
        if (pt-i>=len){
            for (int j=i+len-1;j<pt;j++)
                if (i!=j%N){
                    for (int k=i;k<=j;k++) c[k%N]-=cnt;
                    dfs(d+1);
                    for (int k=i;k<=j;k++) c[k%N]+=cnt;
                }
        }
    }
    void dfs(int d){
        int one=calc();
        if (d>=ans) return;
        if (d+one<ans) ans=d+one;
        if (!one) return;
        for (int i=0;i<=N;i++){
            multi(d,i,2,3);
            multi(d,i,2,2);
            multi(d,i,5,1);
        }
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            ans=INT_MAX;
            for (int i=0;i<=N;i++) c[i]=0;
            for (int i=1;i<=n;i++){
                scanf("%s",name);
                c[strchr(s,name[0])-s]++;
            }
            dfs(0);
            printf("%d
    ",ans);
        }
    }
    

    T - 小马下棋

    Alpha-Beta剪枝,经典博弈树

    把每一状态的所有分支先按照收益排序

    然后递归计算两个估价函数进行剪枝即可

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <climits>
    using namespace std;
    typedef pair<int,int> P;
    typedef pair<int,P> P2;
    const int N=5,K=8;
    int n,k,m[N][N],ans[2],now;
    int dfs(int d,int a,int b){
        P2 tmp[N*N];
        if (d==2*k) return now;
        for (int i=0;i<n-1;i++)
            for (int j=0;j<n-1;j++){
                int t=m[i][j]+m[i+1][j]+m[i][j+1]+m[i+1][j+1];
                tmp[i*(n-1)+j]=P2(t,P(i,j));
            }
        if (d%2==0)
            sort(tmp,tmp+(n-1)*(n-1),greater<P2>());
        else
            sort(tmp,tmp+(n-1)*(n-1),less<P2>());
        for (int k=0;k<(n-1)*(n-1);k++){
            int i=tmp[k].second.first;
            int j=tmp[k].second.second;
            int t=m[i][j];
            now+=m[i][j]+m[i+1][j]+m[i][j+1]+m[i+1][j+1];
            m[i][j]=m[i][j+1],m[i][j+1]=m[i+1][j+1];
            m[i+1][j+1]=m[i+1][j],m[i+1][j]=t;
            if (d%2==0)
                a=max(a,dfs(d+1,a,b));
            else
                b=min(b,dfs(d+1,a,b));
            t=m[i][j];
            m[i][j]=m[i+1][j],m[i+1][j]=m[i+1][j+1];
            m[i+1][j+1]=m[i][j+1],m[i][j+1]=t;
            now-=m[i][j]+m[i+1][j]+m[i][j+1]+m[i+1][j+1];
            if (b<=a) break;
        }
        if (d%2==0)
            return a;
        else
            return b;
    }
    int main(){
        scanf("%d%d",&n,&k);
        ans[0]=0,ans[1]=INT_MAX;
        for (int i=0;i<n;i++)
            for (int j=0;j<n;j++)
                scanf("%d",&m[i][j]);
        printf("%d",dfs(0,INT_MIN,INT_MAX));
    }
    
  • 相关阅读:
    在linux下Ant的环境配置
    在linux下Java的环境配置
    CSS列表逆序
    HTML元素基础学习
    第一天---HTML基础学习
    排球计分程序
    罗辑思维:怎样成为一个高手 观后感
    十八周个人作业
    本周个人作业
    个人作业
  • 原文地址:https://www.cnblogs.com/algonote/p/13085745.html
Copyright © 2011-2022 走看看