The 2016 Asia Regional Contest, Tsukuba

The 2016 Asia Regional Contest, Tsukuba

 

A - Rearranging a Sequence

 一个1到n的有序数组,每次将一个数提前,输出最终序列。

struct node
{
    int x,id;
}a[N];
int cmp(node a,node b)
{
    return a.x<b.x;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int tot=2*n;
        for(int i=n;i>=1;i--) a[i].x=--tot,a[i].id=i;
        while(m--)
        {
            int x;
            scanf("%d",&x);
            a[x].x=--tot;
        }
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++) printf("%d%c",a[i].id,i==n?'\n':' ');
    }
    return 0;
}

B - Quality of Check Digits

 0到9999的数,不足四位高位自动补0,用表生成一个校验码,加在最后面,然后如果这个五位数所有的变形有一种和它生成的校验码冲突了,ans++。

int vis[20][20];
int get_num(int a[],int f)
{
    int he=0;
    for(int i=0;i<f;i++)
        he=vis[he][a[i]];
    return he;
}
int judge(int aa)
{
    //printf("aa=%d\n",aa);
    int a[10];
    for(int i=0;i<10;i++)
        a[i]=0;
    int cont=3;
    while(aa)
    {
        a[cont--]=aa%10;
        aa/=10;
    }
    int num=get_num(a,4);
    a[4]=num;
    int he=get_num(a,5);//printf("num=%d he=%d\n",num,he);
    if(he!=0) return 1;
    for(int i=0;i<5;i++)
    {
        int tmp=a[i];
        for(int j=0;j<=9;j++)
        {//printf("i=%d j=%d\n",i,j);
            a[i]=j;
            if(j==tmp) continue;
            if(get_num(a,5)==he)
            {
//                for(int i=0;i<5;i++)
//                    printf("%d",a[i]);
//                printf("\naa=%d\n",aa);
                return 1;
            }
        }
        a[i]=tmp;
    }//printf("asdasd\n");
    for(int i=0;i<4;i++)
    {
        if(a[i]==a[i+1]) continue;
        swap(a[i],a[i+1]);
        if(get_num(a,5)==he)
        {
//            for(int i=0;i<5;i++)
//                    printf("%d",a[i]);
//                printf("\naa=%d\n",aa);
                return 1;
        }
        swap(a[i],a[i+1]);
    }
    return 0;
}
int main()
{
    for(int i=0; i<10; i++)
        for(int j=0; j<10; j++)
            scanf("%d",&vis[i][j]);
    int sum=0;
    for(int i=0; i<=9999; i++)
    {
        if(judge(i))
        {//printf("iiiiiiiiiiiiiiiiiiii=%d\n",i);
            sum++;
        }
    }
    printf("%d\n",sum);
    return 0;
}

C - Distribution Center

 

 求每条线最多有多少条线上的货物会经过。贪心排序,先把x小的更新,从左往右从右往左各自扫一遍。

int vis[N][2];
struct node
{
    int x,y;
} a[N];
int cmp1(node a,node b)
{
    if(a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
int cmp2(node a,node b)
{
    if(a.x!=b.x) return a.x<b.x;
    return a.y>b.y;
}
int ans[N];
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        cls(vis,0);
        cls(ans,0);
        int mm=m+1,num=0;
        for(int i=1; i<=m; i++)
            scanf("%d%d",&a[i].x,&a[i].y);
        sort(a+1,a+m+1,cmp1);
        for(int i=1; i<=m; i++)
            vis[a[i].y+1][1]=max(vis[a[i].y][1]+1,vis[a[i].y+1][1]);
        sort(a+1,a+m+1,cmp2);
        for(int i=1; i<=m; i++)
            vis[a[i].y][2]=max(vis[a[i].y+1][2]+1,vis[a[i].y][2]);
        for(int i=1; i<=n; i++)
        {
//            printf("y=%d  1==%d 2==%d\n",a[i].y,vis[a[i].y][1],vis[a[i].y][2]);
            ans[i]=vis[i][1]+vis[i][2]+1;
        }
        for(int i=1;i<=n;i++) printf("%d%c",ans[i],i==n?'\n':' ');
    }
    return 0;
}

D - Hidden Anagrams

 

 貌似之前做过,暴力将所有的字串预处理,扔进unorder_set里面,用unorder_map会MLE。

ul base=131;
char s1[N],s2[N];
ul p[N],ha[N],vis[27];
unordered_set<ul>S;
int main()
{
    p[0]=1;
    for(int i=1; i<N; i++) p[i]=p[i-1]*base;
    while(~scanf("%s%s",s1+1,s2+1))
    {
        int len1=strlen(s1+1);
        int len2=strlen(s2+1);
        ha[0]=0;
        S.clear();
        for(int i=1; i<=len1; i++)
        {
            for(int j=0; j<=26; j++) vis[j]=0;
            for(int j=i; j<=len1; j++)
            {
                vis[s1[j]-'a']++;
                ul tmp=0;
                for(int k=0; k<26; k++)
                    tmp=tmp*base+vis[k];
                S.insert(tmp);
            }
        }
        int ans=0;
        for(int i=1; i<=len2; i++)
        {
            for(int j=0; j<=26; j++) vis[j]=0;
            for(int j=i; j<=len2; j++)
            {
                vis[s2[j]-'a']++;
                ul tmp=0;
                for(int k=0; k<26; k++)
                    tmp=tmp*base+vis[k];
                if(S.find(tmp)!=S.end()) ans=max(ans,j-i+1);
            }
        }
        pd(ans);
    }
    return 0;
}


普通set  9600+ms AC。

const int N=4000+10;
char s1[N],s2[N];
int vis[500];
int vis1[N][28],vis2[N][28];
int len1,len2;
//map<ul,int>q;
set<ul>s;
bool judge(int mid)
{
    for(int i=mid; i<=len2; i++)
    {
        ul sum=0;
        for(int k=0; k<26; k++)
            sum+=(sum<<4)+(vis2[i][k]-vis2[i-mid][k]);
        if(s.count(sum)) return true;
    }
    return false;
}
int main()
{
    while(~scanf("%s%s",s1+1,s2+1))
    {
        len1=strlen(s1+1),len2=strlen(s2+1);
//        q.clear();
        s.clear();
        memset(vis1,0,sizeof(vis1));
        memset(vis2,0,sizeof(vis2));
        for(int i=1; i<=len1; i++)
        {
            for(int j=0; j<26; j++) vis1[i][j]=vis1[i-1][j];
            vis1[i][s1[i]-'a']++;
        }
        for(int i=1; i<=len2; i++)
        {
            for(int j=0; j<26; j++) vis2[i][j]=vis2[i-1][j];
            vis2[i][s2[i]-'a']++;
        }
        for(int i=1; i<=len1; i++)
            for(int j=i; j<=len1; j++)
            {
                ul sum=0;
                for(int k=0; k<26; k++)
                    sum+=(sum<<4)+(vis1[j][k]-vis1[i-1][k]);
                s.insert(sum);
//                if(!q[sum]) q[sum]=j-i+1;
//                else q[sum]=max(q[sum],j-i+1);
            }
        int ans=min(len1,len2);
        while(ans)
        {
            if(judge(ans)) break;
            ans--;
        }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值