2018 1.21测试

  套路

文件名:road.cpp(pas)

时间限制:1s

空间限制:512MB

题目描述:

  给出1个 N 个点的有向图,每个点的出度恰好为一。

  现在希望给这 N 条边重定向,求图中不出现环的方案数(对 109 + 7 取模)。

输入格式:

  第一行一个正整数 N

  第二行 N 个正整数 Xi,表示存在一条有向边 i 指向 Xi

输出格式:

  一行,一个整数 Ans,表示定向后不出现环的方案数。

样例读入:

5

2 3 1 5 4

样例输出:

12

数据范围:

对于 30% 的数据,保证 N 20 对于 60% 的数据,保证 N 1000 对于 100% 的数据,保证 N 105

tarjan+组合数学

先tarjan求强连通分量,然后对于强两连分量里面的每一条边我们可以进行正反两种翻转方法,如果一个强连通分量里面有n个点,那么就有n^2种方式,但是注意到出现环的这种情况下我们要减去2,为什么?因为我们要考虑到把这些边全部翻转过来以及都不翻转的时候存在环,那么这种情况就可以直接减去了,然后对于不同种环我们直接让他们相乘就好了(利用乘法原理),然后我们考虑到存在父边的情况,这种情况下,这条边可正可反,那么就是两种情况我们直接ans*2就好了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 101000
#define LL long long
#define mod 1000000007
using namespace std;
LL ans;bool vis[N];
int n,x,y,s,tim,top,sum,tot;
int to[N],dfn[N],low[N],head[N],stack[N],nextt[N],belong[N];
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return x*f;
}
int add(int x,int y)
{
    tot++;
    to[tot]=y;
    nextt[tot]=head[x];
    head[x]=tot;
}
int tarjan(int x)
{
    low[x]=dfn[x]=++tim;
    stack[++top]=x;vis[x]=true;
    for(int i=head[x];i;i=nextt[i])
    {
        int t=to[i];
        if(vis[t]) low[x]=min(low[x],dfn[t]);
        else if(!dfn[t]) tarjan(t),low[x]=min(low[x],low[t]);
    }
    if(low[x]==dfn[x])
    {
        sum++,belong[sum]++;
        for(;stack[top]!=x;top--)
        {
            int t=stack[top];
            vis[t]=false;
            belong[sum]++;
        }
        top--,vis[x]=false;
    }
}
LL qpow(int a,LL b)
{
    LL res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        b>>=1;a=1ll*a*a%mod;
    }
    return res-2;
}
int main()
{
    freopen("road.in","r",stdin);
    freopen("road.out","w",stdout);
    n=read();s=ans=1;
    for(int i=1;i<=n;i++)
     x=read(),add(x,i);
    for(int i=1;i<=n;i++)
     if(!dfn[i])
     {
        tarjan(i);
        for(int j=s;j<=sum;j++)
         if(belong[j]>1) ans=ans*qpow(2,belong[j])%mod;
         else ans=ans*2%mod;
        s=sum+1;
     }
    printf("%I64d",ans);
    return 0;
}

AC代码

  exLCS

文件名:lcs.cpp(pas)

时间限制:1s

空间限制:512MB

题目描述:

给出两个仅有小写字母组成的字符串 str1 和 str2,试求出两个串的最长公共子序列。公共子序列定义如下:

若有 a1 < a2 < < ak  b1 < b2 < < bk,满足

str1[ai] = str2[bi]; 8i 2 f1; 2; 3; ; kg;

则称找到了一个长度为 k 的公共子序列。

输入格式:

第一行一个字符串 str1。第二行一个字符串 str2

输出格式:

一行,一个整数,表示 str1 与 str2 的最长公共子序列的长度。

样例读入:

abdcba abafdsfa

样例输出:

4

样例解释:

如果字符串从 0 开始标号,可以验证 fang = f0; 1; 2; 5gfbng = f0; 1; 4; 7g 是满足要求的方案。

数据范围:

对于 10% 的数据,保证 jstr1j 10; jstr2j 10 对于 30% 的数据,保证 jstr1j 20; jstr2j 30

对于 60% 的数据,保证 jstr1j 1000; jstr2j 1000 对于 100% 的数据,保证 jstr1j 1000; jstr2j 106

 

60分lcs朴素dp

f[i][j]=f[i-1][j-1]+1;(if(a[i]==b[j]) i表示a字符串匹配到第i位,j表示b字符串匹配到第j位

f[i][j]=max(f[i][j],max(f[i-1][j],f[i][j-1]));

/*最大公共子序列问题               
 在解决最长公共子序列(LCS)问题,即求字符串A,B的公共子序列LCS(注意:LCS不一定连续,但和原始序列的元素顺序有关)中长度最长的公共子序列时,因为最长公共子序列不唯一,但是最长公共子序列长度是一定的,所以先把问题简化,如何求两个序列的最长公共子序列长度?                                    
    我们首先想到的肯定是暴力枚举法。                                                                       先来看看:假设序列A有n 个元素,序列B有 m 个元素,那么A,B分别有2^n,2^m个子序列,如果任意两个子序列一一比较,比较的的子序列高达2^(m+n)对,这还没有算具体的复杂度。
    所以我们可以试试动态规划,把这个问题分解成子问题:求A的前i个元素和B的前j个元素之间的最长公共子序列长度。这时的空间复杂度为o(m+n)。

算法思想 
1、定义dp [i][j]:表示字符串序列A的前i个字符组成的序列Ax和字符串序列B的前j个字符组成的序列By之间的最长                   公共子序列L(i,j )的长度(m ,n分别为Ax和By的长度,i<=m,j<=n)
2、如果Ax [i] =By [j],那么Ax与By之间的最长公共子序列L( i,j )的最后一项一定是这个元素,
   所以dp [i][j] = dp[i-1][j-1] + 1。
3、如果Ax[i] != By[j],设LCS(i-1,j-1)是L( i -1, j-1 )的最后一个元素,或者L(i-1,j-1)是空序列,
   则 t!= Ax[i]和t!=By[j]至少有一个不成立。
   (1)    当 LCS(i-1,j-1) != Ax[i] 时,dp[i][j]= dp[i-1][j];
   (2)    当 LCS(i-1,j-1) != By[j] 时,ap[i][j]= dp[i][j-1];
   所以dp[i][j]= max ( dp[i-1][j],dp[i][j-1] )。                         
4、初始值为:dp[0][j] = dp[i][0] = 0.
5、题意要求求出任意一个最长公共子序列,这点要如何实现呢?
   仍然考虑上面的递推式,L(i,j)的最后一个元素LCS( i,j )的来源有三种情况,定义数组flag[MAXN][MAXN]用    以标记来的方向:
  (1) dp[i][j] = dp[i-1][j-1] + 1,对应字符LCS( i-1,j-1)接上LCS( i,j),flag[i][j] = 1,表示从斜向上      左方来;
  (2) dp[i][j] = dp[i-1][j],对应字符LCS(i-1,j)接上LCS(i,j),flag[i][j] = 2,表示从上方过来;
  (3) dp[i][j] = dp[i][j-1],对应字符LCS(I,j-1)接上LCS(i,j),flag[i][j] = 3,表示从左方过来。
   
   我们只要在计算dp[i][j]时根据来源进行不同的标记,回溯就可以找到一个最长公共子序列。

*/   

lcs讲解

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1010
using namespace std;
char a[N],b[N];
int l1,l2,f[N][N],ans;
int main()
{
    freopen("lcs.in","r",stdin);
    freopen("lcs.out","w",stdout);
    cin>>a+1>>b+1;
    l1=strlen(a+1),l2=strlen(b+1);
    for(int i=1;i<=l1;i++)
     for(int j=1;j<=l2;j++)
     {
         if(a[i]==b[j]) f[i][j]=f[i-1][j-1]+1;
         f[i][j]=max(f[i][j],max(f[i-1][j],f[i][j-1]));
     }
    ans=f[l1][l2];
    printf("%d",ans);
    return 0;
}

60代码

魔方

文件名:cube.cpp(pas)

时间限制:1s

空间限制:512MB

题目描述:

给出一个二阶魔方,保证 N 步以内能够还原。“还原” 被定义为每个面均为纯色。请给出,操作编号字典序最小,且不存在同类操作相邻,的还原方案。


C1


C2


顶面


C3


C4


C9   C10   C5


C6   C13   C14


左面


前面


右面


C11


C12


C7


C8


C15   C16


C17


C18


C1


C2


底面


C19


C20


C3


C4


C14


C5


C6


C13


C21


C22


C16


后面


C15


C7


C8


C23


C24


操作编号


操作类别


操作描述


操作编号


操作类别


操作描述


1


A


顶面顺时针旋转 90?


10


D


右面顺时针旋转 90?


2


A


顶面顺时针旋转 180?


11


D


右面顺时针旋转 180?


3


A


顶面顺时针旋转 270?


12


D


右面顺时针旋转 270?


4


B


左面顺时针旋转 90?


13


E


后面顺时针旋转 90?


5


B


左面顺时针旋转 180?


14


E


后面顺时针旋转 180?


6


B


左面顺时针旋转 270?


15


E


后面顺时针旋转 270?


7


C


前面顺时针旋转 90?


16


F


底面顺时针旋转 90?


8


C


前面顺时针旋转 180?


17


F


底面顺时针旋转 180?


9


C


前面顺时针旋转 270?


18


F


底面顺时针旋转 270?

表 1: 注: 此处某面的 “顺时针” 是指从魔方外部正视该面时的顺时针方向

输入格式:

第一行一个正整数 N,表示最多步数。

接下来 24 个整数,按上图的顺序依次给出 CiCi 2 f1; 2; 3; 4; 5; 6g

输出格式:

一行,t 个用空格隔开的正整数,表示复原的最小字典序操作序列,要求 0 < t <N。最后一个数后无空格。

数据保证输入魔方是打乱的。

注:(1,2,3) 虽然长度长于 (2,3),但字典序更小。

样例读入:

2

1 1 1 1

4 4 2 2

6 6 3 3

3 3 6 6

5 5 5 5

4 4 2 2

样例输出:

2

样例解释:

因为不能类别相同的操作相邻,所以只有 2 种操作方式可以在两步内复原此时的魔方:

(2),(17),故字典序最小的为 (2)。

数据范围:

对于 20% 的数据,保证 N = 1

对于 40% 的数据,保证 N<=3

对于另 20% 的数据,保证 N <=6,且保证答案只用到前 6 种操作对于 100% 的数据,保证 N <=7

大模拟??

据说很恶心、、、

#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;
}

某X姓大佬代码

原文地址:https://www.cnblogs.com/z360/p/8325460.html

时间: 2024-10-05 10:58:20

2018 1.21测试的相关文章

2018/8/21 qbxt测试

2018/8/21 qbxt测试 期望得分:0? 实际得分:0 思路:manacher   会写模板但是不会用 qwq 听了某人的鬼话,直接输出0,然后就gg了 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = (int)2e6 + 10; typedef long long ll;

2018冬令营模拟测试赛(五)

2018冬令营模拟测试赛(五) [Problem A][UOJ#154]列队 试题描述 picks 博士通过实验成功地得到了排列 \(A\),并根据这个回到了正确的过去.他在金星凌日之前顺利地与丘比签订了契约,成为了一名马猴烧酒. picks 博士可以使用魔法召唤很多很多的猴子与他一起战斗,但是当猴子的数目 \(n\) 太大的时候,训练猴子就变成了一个繁重的任务. 历经千辛万苦,猴子们终于学会了按照顺序排成一排.为了进一步训练,picks 博士打算设定一系列的指令,每一条指令 \(i\) 的效果

2018冬令营模拟测试赛(三)

2018冬令营模拟测试赛(三) [Problem A]摧毁图状树 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见"试题描述" 数据规模及约定 见"试题描述" 题解 这题没想到贪心 QwQ,那就没戏了-- 贪心就是每次选择一个最深的且没有被覆盖的点向上覆盖 \(k\) 层,因为这个"最深的没有被覆盖的点"不可能再有其它点引出的链覆盖它了,而它又

2018冬令营模拟测试赛(十七)

2018冬令营模拟测试赛(十七) [Problem A]Tree 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见"试题描述" 数据规模及约定 见"试题描述" 题解 这个数据范围肯定是树上背包了. 令 \(f(i, j, k)\) 表示子树 \(i\) 中选择了 \(j\) 个节点,路径与根的连接情况为 \(k\),具体地: \(k = 0\) 时,路径的两个端点

2018冬令营模拟测试赛(十九)

2018冬令营模拟测试赛(十九) [Problem A]小Y 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见"试题描述" 数据规模及约定 见"试题描述" 题解 目前未知. 这题目前就能做到 \(O(n \sqrt{M} \log n)\),其中 \(M\) 是逆序对数,然而会被卡 \(T\):当然这题暴力可以拿到和左边那个算法一样的分数,只要暴力加一个剪枝:当左

三级菜单-2018.2.21

根据老男孩课程以及网上的代码,自行打出的代码,虽然参照的比较多,嘿嘿嘿 #_author_:"Bushii" #data:2018/2/21 menu= { '山东' : { '青岛' : ['四方','黄岛','崂山','李沧','城阳'], '济南' : ['历城','槐荫','高新','长青','章丘'], '烟台' : ['龙口','莱山','牟平','蓬莱','招远'] }, '江苏' : { '苏州' : ['沧浪','相城','平江','吴中','昆山'], '南京' :

2018/7/21 Python 爬虫学习

2018/7/21,这几天整理出来的一些Python 爬虫学习代码. import urllib2 response = urllib2.urlopen("http://baidu.com") html = response.read() print html 进一步,可以request import urllib2 req = urllib2.Request("http://www.baidu.com") response = urllib2.urlopen(re

Microsoft Artificial Intelligence Conference(2018.05.21)

时间:2018.05.21地点:北京嘉丽大酒店 原文地址:https://www.cnblogs.com/xuefeng1982/p/10335943.html

2018.4.21 五周第四次课(shell特殊符号,cut截取等命令)

shell特殊符号_cut命令 概念:cut命令用来截取某一个字段 格式:cut -d '分割字符' [-cf] n,这里的n是数字,该命令选项有如下几个: - d 后面跟分割字符,分割字符要用单引号括起来 - c 后面接的是第几个字符 - f 后面接的是第几个区块 cut命令用法如下 [[email protected] do]# cat /etc/passwd |head -2root:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/no