【题解】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\n%s\n%lld",a,b,&d);
        ll ans=solve(b,d);
        ans=(ans+(dep[pd]==d))%K;
        ans=(K+ans-solve(a,d))%K;
        printf("%lld\n",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\t%s\t%s\t%s\t%s\t%lld\n",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=='\n'){
            ch=getchar();
            if (!jmp.empty()) break;
            while(1){
                while(ch==' '){ch=getchar();}ll n=0;
                if (ch=='\n') 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=='\n'||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\n",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));
}
posted @ 2020-06-10 15:54  Byaidu  阅读(337)  评论(0编辑  收藏  举报