alpc training 2013-7-31

A:

我采用游程编码的方法,就是讲aaaabbbc这样的字符串变成[4]a[3]b[1]c

然后就是暴力地扫描就行了。

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>

using namespace std;
#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define DOR(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define oo 1<<30
#define eps 1e-6
#define nMax 1000010
#define F first
#define S second

char s1[nMax],s2[nMax],s3[nMax];
int a[30],b[30];
int n1[nMax],n2[nMax];

int main(){
#ifndef ONLINE_JUDGE
    //freopen("input.txt","r",stdin);
#endif
    while(cin>>s1>>s2){
        int l1=strlen(s1),l2=strlen(s2);
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        int i=0,j=0,ans=1;
        for(i=0;i<l1;i++) a[s1[i]-'a']=1;
        for(i=0;i<l2;i++) b[s2[i]-'a']=1;
        for(int i=0;i<30;i++) if(b[i]&&!a[i]) {
            printf("-1\n");
            ans=0;
            break;
        }
        if(ans==0) continue;
        int k=0;
        for(i=0;i<l1;i++) if(b[s1[i]-'a']==1) s3[k++]=s1[i];l1=k;
        for(k=0,i=0;i<l1;) {
            j=i;while(j<l1 && s3[i]==s3[j]) j++;
            s1[k]=s3[i];n1[k]=j-i;i=j;k++;
        }
        l1=k;
        for(k=0,i=0;i<l2;){
            j=i;while(j<l2 && s2[i]==s2[j]) j++;
            s3[k]=s2[i];n2[k]=j-i;i=j;k++;
        }
        l2=k;

        j=0,i=0;
        ans =0;
        while(j<l2){
            while(1){
                if(i==0) ans ++;
                k=0;
                if(s1[i]==s3[j]){
                    if(n1[i]>=n2[j]) {j=j+1;k=1;}
                    else n2[j]-=n1[i];
                }
                i+=1;
                if(i==l1) i=0;
                if(k) break;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

B:

将每个点用map哈希一下,然后找个入度为1的点,dfs就行了。

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>

using namespace std;
#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define DOR(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define oo 1<<30
#define eps 1e-6
#define nMax 200010
#define F first
#define S second

int h[nMax];
map<int,int> ha;
int n,cnt;
int first[nMax],to[nMax],nxt[nMax],e,in[nMax];
void addadge(int u,int v) {
    to[e]=v;nxt[e]=first[u];first[u]=e;e++;
    to[e]=u;nxt[e]=first[v];first[v]=e;e++;
}
int find(int u){
    if(ha.count(u)) return ha[u];
    ha[u]=cnt;
    h[cnt]=u;
    cnt++;
    return ha[u];//,cnt-1;
}
int main(){
#ifndef ONLINE_JUDGE
    //freopen("input.txt","r",stdin);
#endif
    while(~scanf("%d",&n)){
        int u,v,x,y;
        e=0;
        FOR(i,0,n) first[i]=-1,in[i]=0;
        ha.clear();cnt=0;
        FOR(i,1,n) {
            scanf("%d%d",&u,&v);
            x=find(u);y=find(v);
            addadge(x,y);
            in[x]++;in[y]++;
        }
        FOR(i,0,n) if(in[i]==1) {x=i;break;}
        int ok=1;
        while(ok){
            printf("%d ",h[x]);
            in[x]=0;
            ok=0;
            for(int i=first[x];i!=-1;i=nxt[i]) if(in[to[i]]) {
                ok=1;
                x=to[i];break;
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值