2013暑假集训第二天下午总结

比赛地址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=26100#rank

都是些陈题,好多以前做过了都。

A:问第一个字符串是不是第二个的子串(非连续也可以)

直接遍历一边就行了。

#define maxn 100005

char s[maxn],t[maxn];
int l1,l2;
int main()
{
    while(scanf("%s%s",&s,&t)!=EOF)
    {
        l1 = strlen(s);
        l2 = strlen(t);
        int i = 0 ;
        int j = 0;
        while(j < l1 && i < l2)
        {
            if(s[j] == t[i] )
            {
                i ++ ;
                j ++ ;
            }
            else i ++ ;
        }
        if(j != l1 )
        {
            printf("No
");
        }
        else printf("Yes
");
    }
    return 0;
}
View Code

B:以前做的,就是括号的两种表示法的转化,p法表示是每一个右括号前面的左括号的个数组成的序列,w法是每个右括号的与之对应的左括号中间的左右括号个数+1 组成的序列。

算是栈的应用吧 http://www.cppblog.com/jh818012/articles/164779.html 以前的做的地址

#define maxn 100

int a[maxn];
int b[maxn];
int c[maxn];
int n ;
int num;
int main()
{
    int t;
    scanf("%d",&t);
    while(t -- ) {
        scanf("%d",&n);
        for(int i = 1 ; i <= n ; i ++ ) scanf("%d",&a[i]);
        num = 0 ;
        int i , j ;
        i = 1;
        j = 0 ;
        while(i <= n ) {
            while(num < a[i]) {
                num ++ ;
                c[++j] = -1 ;
            }
            c[++j] = 1;
            i ++ ;
        }
        int tt = j ;
        int x,x1 ;
        num = 0 ;
        for(i = 1 ; i <= tt; i ++  )
            if(c[i] == 1) {
                j = i - 1;
                x = 1 ;
                x1 = 0 ;
                while(j > 0 ) {
                    if(c[j] < 0  ) x1 ++ ;
                    x += c[j];
                    if(x == 0 ) break;
                    j -- ;
                }
                b[++num ] = x1;
               // printf("%d
",x1);
            }

        for(i = 1 ; i <= n ; i++ ) {
            printf("%d",b[i]);
            if(i != n ) printf(" ");
        }
        printf("
");
    }
    return 0;
}
View Code

C:树的前序遍历和中序遍历求后续遍历

递归求解

char str1[100],str2[100];

void dfs(int s1,int t1,int s2,int t2 )
{
    if(s1 < 0 || t1 < 0 || s2 < 0 || t2 < 0 ) return  ;
    if(s1 > t1 || s2 > t1 ) return ;
    if(t1 == s1)
    {
        printf("%c",str1[s1]);
        return ;
    }
    int m1,m2;
    m2 = s2;
    while(str2[m2] != str1[s1]) m2 ++ ;
    m1 = s1 + (m2 - s2);
    dfs(s1 + 1 , m1 , s2 , m2 - 1  );
    dfs(m1 + 1 , t1 , m2 + 1 , t2 );
    printf("%c",str1[s1]);
    return ;
}
int main()
{
    int len ;
    while(scanf("%s%s",&str1,&str2)!=EOF)
    {
        len = strlen(str1);
        dfs(0,len - 1 ,0,len - 1 );
        printf("
");
    }
    return 0;
}
View Code

D:水bfs,想让大家练一下队列。注意边界,vis的初始化和n,k为0的情况(这里贡献wa两次)

#define maxn 400005

struct node
{
    int x,step;
};

queue<node> q ;
int n,k;
bool vis[maxn];
int bfs()
{
    while(!q.empty()) q.pop();
    memset(vis,0,sizeof(vis));
    node tmp, u ;
    tmp.x = n ;
    tmp.step = 0;
    vis[n] = 1 ;
    q.push(tmp);
    while(!q.empty())
    {
        u = q.front();
        q.pop();
        if(u.x == k ) return u.step;
        //
        tmp.x = u.x - 1 ;
        tmp.step = u.step + 1 ;
        if(tmp.x >= 0 && !vis[tmp.x])
        {
            q.push(tmp);
            vis[tmp.x] = 1;
        }
        //
        tmp.x = u.x + 1 ;
        //tmp.step = u.step + 1 ;
        if(tmp.x >= 0 && tmp.x < 200000 && !vis[tmp.x])
        {
            q.push(tmp);
            vis[tmp.x] = 1;
        }
        //
        tmp.x = u.x * 2;
        //tmp.step = u.step + 1 ;
        if(tmp.x >= 0 && tmp.x < 200000 && !vis[tmp.x])
        {
            q.push(tmp);
            vis[tmp.x] = 1;
        }
    }
}
int main()
{
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        int ans = bfs();
        printf("%d
",ans);
    }
    return 0;
}
View Code

E:并查集吧。题意是说n个人,m个团队,每个人可能参加多个团队(也有人不参加团队),已知0号是suspects 。如果队伍中某个人是suspects,那么这整个队伍都是suspects 。求总的suspects 的个数。

直接用并查集表示关系集合。把数据中的每组的第一个人作为代表元,其他人与他合并关系。最后统计与0相同父亲的人有多少个就行了。

#define maxn 30005
int father[maxn];
int n,m;


int find(int x )
{
    if(x == father[x] ) return x;
    father[x] = find(father[x]) ;
    return father[x];
}
void unit(int u,int v)
{
    father[find(v)] = find(u);
}
void init()
{
    for(int i = 0 ; i < maxn ; i ++ )  father[i] = i ;
}
int main()
{
    int tn,db;
    int x ;
    while(scanf("%d%d",&n,&m)!=EOF && !(m == 0 && n == 0))
    {
        init();
        for(int i = 0 ; i < m ; i ++ )
        {
            scanf("%d",&tn);
            if(tn == 0 ) continue ;
            tn -- ;
            scanf("%d",&db);
            for(int j = 0 ; j < tn ; j ++ )
            {
                scanf("%d",&x);
                unit(db,x);
            }
        }
        int tt;
        tt = find(0);
        int ans ;
        ans = 1 ;
        for(int i = 1; i < n ;i ++ )
        {
            if(find(i) == tt)
            {
                ans ++ ;
            }
        }
        printf("%d
",ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/jh818012/p/3193471.html