2017北京国庆刷题Day5 afternoon

期望得分:100+60+100=260

实际得分:0+60+40=100

 

 

设图中有m个环,每个环有si条边,有k条边不在环中

ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)…… *( 2^sm -2)* 2^k

(环上的边只有两种可能形成环)

 

找环好找,怎么找树?

一种方法是tarjan找出所有的环,总边数-环的边数=树的边数

std用了拓扑排序

 

考场上忘了树的情况,爆零了。

注意:n个点n条边是环套树森林

 

#include<cstdio>
#define N 100001
using namespace std;
typedef long long LL;
int to[N],d[N],q[N],sum;
const int mod=1e9+7;
LL pow(LL a,int b)
{
    LL res=1;
    for(;b;b>>=1,a=a*a%mod)
        if(b&1) res=res*a%mod;
    return res;
}
void dfs(int x)
{
    sum++;
    d[x]=0;
    if(d[to[x]]) dfs(to[x]);
}
int main()
{
    freopen("road.in","r",stdin);
    freopen("road.out","w",stdout);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&to[i]),d[to[i]]++;
    int h=1,t=0;
    for(int i=1;i<=n;i++)
        if(!d[i]) q[++t]=i;
    while(h<=t)
    {
        if(!(--d[to[q[h]]])) q[++t]=to[q[h]];
        ++h;
    }
    LL ans=pow(2,t); 
    for(int i=1;i<=n;i++)
        if(d[i])
        {
            sum=0;
            dfs(i);
            ans=ans*(pow(2,sum)-2)%mod;
        }
    printf("%I64d",ans);
}
View Code

 

 

本题60分是经典的n^2 LCS问题

第一个串长1000,第二个串长1e6

很显然枚举只能枚举第一个串

n^2 中是dp[i][j] 表示第一个字符串的前i个字符 与 第二个字符串的前j个字符 的 最长公共子串长度

它的优化是:

dp[i][j] 表示 第一个字符串的前i个字符,与 第二个字符串匹配了长为j的最长公共子串,第j个字符在第二个字符串中的最左下标

这样最后倒序枚举 j,当dp[len1][j]<=len2 时,输出j,return 0

如何转移?

考虑顺推

第一个字符串的第i+1 位如果不发生匹配,那么dp[i+1][j]=min(dp[i+1][j],dp[i][j])

第i+1位如果发生匹配,那么dp[i+1][j+1]=min(dp[i+1][j+1],nxt[dp[i][j]+1][s1[i+1]])

其中nxt[i][j]表示在第二个字符串中,第i位及后面最早出现字符j的位置

 

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

#define N 1001
#define M 1000001

char s1[N],s2[M];
int nxt[M][26],dp[N+2][N];

int main()
{
    freopen("lcs.in","r",stdin);
    freopen("lcs.out","w",stdout);
    scanf("%s%s",s1+1,s2+1);
    int len1=strlen(s1+1),len2=strlen(s2+1);
    for(int i=0;i<26;i++) nxt[len2+1][i]=len2+5;
    for(int i=len2;i>=0;i--)
        for(int j=0;j<26;j++)
            if(s2[i]-'a'==j) nxt[i][j]=i;
            else nxt[i][j]=nxt[i+1][j];
    memset(dp,63,sizeof(dp));
    for(int i=0;i<=len1;i++) dp[i][0]=0;
    for(int i=0;i<len1;i++)
        for(int j=0;j<=i && dp[i][j]<=len2;j++)
        {
            dp[i+1][j]=min(dp[i+1][j],dp[i][j]);
            if(j<len1) dp[i+1][j+1]=min(dp[i+1][j+1],nxt[dp[i][j]+1][s1[i+1]-'a']); 
        }
    for(int i=len1;i>=0;i--)
        if(dp[len1][i]<=len2) { printf("%d\n",i); return 0; }    
} 
View Code

 

60分暴力:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1001
using namespace std;
char s1[N],s2[N];
int l1,l2;
int dp[N][N];
int main()
{
    freopen("lcs.in","r",stdin);
    freopen("lcs.out","w",stdout);
    scanf("%s%s",s1+1,s2+1);
    l1=strlen(s1+1); l2=strlen(s2+1);
    for(int i=1;i<=l1;i++)
        for(int j=1;j<=l2;j++)
            if(s1[i]==s2[j]) dp[i][j]=dp[i-1][j-1]+1;
            else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
    printf("%d",dp[l1][l2]);
}
View Code

 

 

 

题面修改:后面的DEF分别改为CBA

首先很关键的一点:

因为要求操作字典序最小,所以DEF没有用

例如:下面转90相当于上面转270

然后 大模拟 

考场上复制时漏改一个数组,丢了60分o(╥﹏╥)o

#include<cstdio>
#include<algorithm>
using namespace std;
int n,tmp[10];
int ans[10];
int L[2][2],R[2][2],U[2][2],D[2][2],F[2][2],B[2][2];
bool ok;
bool judge(int sum)
{
    if(!(L[0][0]==L[0][1] && L[0][1]==L[1][0] && L[1][0]==L[1][1])) return false;
    if(!(R[0][0]==R[0][1] && R[0][1]==R[1][0] && R[1][0]==R[1][1])) return false;
    if(!(U[0][0]==U[0][1] && U[0][1]==U[1][0] && U[1][0]==U[1][1])) return false;
    if(!(D[0][0]==D[0][1] && D[0][1]==D[1][0] && D[1][0]==D[1][1])) return false;
    if(!(F[0][0]==F[0][1] && F[0][1]==F[1][0] && F[1][0]==F[1][1])) return false;
    if(!(B[0][0]==B[0][1] && B[0][1]==B[1][0] && B[1][0]==B[1][1])) return false;
    for(int i=1;i<=sum;i++) ans[i]=tmp[i];
    ans[0]=sum;
    return true;
} 
void self90(int k[2][2],int a1,int a2,int b1,int b2,int c1,int c2,int d1,int d2)
{
    int t=k[a1][a2];
    k[a1][a2]=k[b1][b2]; k[b1][b2]=k[c1][c2]; k[c1][c2]=k[d1][d2]; k[d1][d2]=t;
}
void other90(int k1[2][2],int a1,int a2,int k2[2][2],int b1,int b2,int k3[2][2],int c1,int c2,int k4[2][2],int d1,int d2)
{
    int t=k1[a1][a2];
    k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
    a2^=1; b2^=1; c2^=1; d2^=1;
    t=k1[a1][a2];
    k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
}
void other90_(int k1[2][2],int a1,int a2,int k2[2][2],int b1,int b2,int k3[2][2],int c1,int c2,int k4[2][2],int d1,int d2)
{
    int t=k1[a1][a2];
    k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
    a1^=1; b1^=1; c1^=1; d1^=1;
    t=k1[a1][a2];
    k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
}
void other90_3(int k1[2][2],int a1,int a2,int k2[2][2],int b1,int b2,int k3[2][2],int c1,int c2,int k4[2][2],int d1,int d2)
{
    int t=k1[a1][a2];
    k1[a1][a2]=k2[b1][b2]; k2[b1][b2]=k3[c1][c2]; k3[c1][c2]=k4[d1][d2]; k4[d1][d2]=t;
}
void self180(int k[2][2],int a1,int a2,int b1,int b2,int c1,int c2,int d1,int d2)
{
    swap(k[a1][a2],k[b1][b2]);
    swap(k[c1][c2],k[d1][d2]);
}
void other180(int k1[2][2],int a1,int a2,int k2[2][2],int b1,int b2,int k3[2][2],int c1,int c2,int k4[2][2],int d1,int d2)
{
    swap(k1[a1][a2],k2[b1][b2]);
    swap(k3[c1][c2],k4[d1][d2]);
    a2^=1; b2^=1; c2^=1; d2^=1;
    swap(k1[a1][a2],k2[b1][b2]);
    swap(k3[c1][c2],k4[d1][d2]);
}
void other180_(int k1[2][2],int a1,int a2,int k2[2][2],int b1,int b2,int k3[2][2],int c1,int c2,int k4[2][2],int d1,int d2)
{
    swap(k1[a1][a2],k2[b1][b2]);
    swap(k3[c1][c2],k4[d1][d2]);
    a1^=1; b1^=1; c1^=1; d1^=1;
    swap(k1[a1][a2],k2[b1][b2]);
    swap(k3[c1][c2],k4[d1][d2]);
}
void other180_3(int k1[2][2],int a1,int a2,int k2[2][2],int b1,int b2,int k3[2][2],int c1,int c2,int k4[2][2],int d1,int d2)
{
    swap(k1[a1][a2],k2[b1][b2]);
    swap(k3[c1][c2],k4[d1][d2]);
}
void dfs(int x,char ty)
{
    if(ok) return;
    if(judge(x-1)) { ok=true; return; }
    if(x==n+1) return;
    if(ty!='A')
    {
        self90(U,0,0,1,0,1,1,0,1); 
        other90(F,0,0,R,0,0,B,0,1,L,0,1);
        tmp[x]=1; dfs(x+1,'A');
        if(ok) return;
        self90(U,0,0,0,1,1,1,1,0);
        other90(F,0,0,L,0,1,B,0,1,R,0,0);
        
        self180(U,0,0,1,1,0,1,1,0);
        other180(F,0,0,B,0,1,R,0,0,L,0,1);
        tmp[x]=2; dfs(x+1,'A');
        if(ok) return;
        self180(U,0,0,1,1,0,1,1,0);
        other180(F,0,0,B,0,1,R,0,0,L,0,1);
        
        self90(U,0,0,0,1,1,1,1,0);
        other90(F,0,0,L,0,1,B,0,1,R,0,0);
        tmp[x]=3; dfs(x+1,'A');
        self90(U,0,0,1,0,1,1,0,1); 
        other90(F,0,0,R,0,0,B,0,1,L,0,1);
        if(ok) return;
        
    }
    if(ty!='B')
    {
        self90(L,0,0,0,1,1,1,1,0);
        other90_(F,0,0,U,0,0,B,1,0,D,1,0);
        tmp[x]=4; dfs(x+1,'B');
        if(ok) return;
        self90(L,0,0,1,0,1,1,0,1);
        other90_(F,0,0,D,1,0,B,1,0,U,0,0);
        
        self180(L,0,0,1,1,0,1,1,0);
        other180_(F,0,0,B,1,0,U,0,0,D,1,0);
        tmp[x]=5; dfs(x+1,'B');
        if(ok) return;
        self180(L,0,0,1,1,0,1,1,0);
        other180_(F,0,0,B,1,0,U,0,0,D,1,0);
        
        self90(L,0,0,1,0,1,1,0,1);
        other90_(F,0,0,D,1,0,B,1,0,U,0,0);
        tmp[x]=6; dfs(x+1,'B');
        if(ok) return;
        self90(L,0,0,0,1,1,1,1,0);
        other90_(F,0,0,U,0,0,B,1,0,D,1,0);
    }
    if(ty!='C')
    {
        self90(F,0,0,1,0,1,1,0,1);
        other90_3(R,0,0,U,1,0,L,1,0,D,1,1);
        other90_3(R,1,0,U,1,1,L,0,0,D,1,0);
        tmp[x]=7; dfs(x+1,'C');
        if(ok) return;
        self90(F,0,0,0,1,1,1,1,0);
        other90_3(R,0,0,D,1,1,L,1,0,U,1,0);
        other90_3(R,1,0,D,1,0,L,0,0,U,1,1);
        
        self180(F,0,0,1,1,0,1,1,0);
        other180_3(R,0,0,L,1,0,U,1,0,D,1,1);
        other180_3(R,1,0,L,0,0,U,1,1,D,1,0);
        tmp[x]=8; dfs(x+1,'C');
        if(ok) return;
        self180(F,0,0,1,1,0,1,1,0);
        other180_3(R,0,0,L,1,0,U,1,0,D,1,1);
        other180_3(R,1,0,L,0,0,U,1,1,D,1,0);
        
        self90(F,0,0,0,1,1,1,1,0);
        other90_3(R,0,0,D,1,1,L,1,0,U,1,0);
        other90_3(R,1,0,D,1,0,L,0,0,U,1,1);
        tmp[x]=9; dfs(x+1,'C');
        if(ok) return;
        self90(F,0,0,1,0,1,1,0,1);
        other90_3(R,0,0,U,1,0,L,1,0,D,1,1);
        other90_3(R,1,0,U,1,1,L,0,0,D,1,0);
    }
}
int main()
{
    freopen("cube.in","r",stdin);
    freopen("cube.out","w",stdout);
    scanf("%d",&n);
    scanf("%d%d%d%d",&U[0][0],&U[0][1],&U[1][0],&U[1][1]);
    scanf("%d%d%d%d",&F[0][0],&F[0][1],&F[1][0],&F[1][1]);
    scanf("%d%d%d%d",&L[0][1],&L[0][0],&L[1][1],&L[1][0]);
    scanf("%d%d%d%d",&R[0][0],&R[0][1],&R[1][0],&R[1][1]);
    scanf("%d%d%d%d",&D[1][0],&D[1][1],&D[0][0],&D[0][1]);
    scanf("%d%d%d%d",&B[1][0],&B[1][1],&B[0][0],&B[0][1]);
    dfs(1,'G');
    for(int i=1;i<=ans[0];i++) printf("%d ",ans[i]);
    return 0;
}
View Code

 

posted @ 2017-10-09 21:39  TRTTG  阅读(242)  评论(0编辑  收藏  举报