• 2014.7.8模拟赛【词编码】


    一个发送机可以通过一条隧道发送一些以二进制代码组成的单词。在其尽头的接收机可以使用特殊技术恢复到最初的单词。每个单词最初都由0和1组成。所有的单词最-初长度都为n(4≤N  ≤l000)。当穿过隧道之后单词可能发生以下几种情况之一:

        (1)任意(一个)0被1取代

        (2)任意(一个)符号被删除

        (3)一个符号(0或1)被插入到任何位置

        (4)不改变

        我们知道最初的单词都具有以下性质:有1的位置号的总和是N+1的倍数,或者是0.

        Input

        N和转换后的单词,每个单词占一行。单词数不大于2001,不会有其它任何东西,除了一些空格与空行。

        Outpul

        你的程序应该打印输出原始序列的词,注意换行:    。

        若有多解,操作4优先,不行则按操作1,2,3优先。同一操作,按操作位置最先的优先(从左到右数起l,2,3,…N),还有操作2时,被删数列,先在被删数列添0,不行再添1。如果没答案输出-1

        Sample Input

        4

        0000

        011

        1011

        11011

        Sample Output

        0000

        0110

        1001

        1111

    水题……就是模拟,但是我在考场上看错题目以为有无限次操作,结果爆蛋了

    其实只有一次操作。然后按它给的顺序找原串就行了

    #include<cstdio>
    #include<cstring>
    inline 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 n,len,sum;
    char ch[2010];
    int f[2010];
    int main()
    {
    	freopen("word,in","r",stdin);
    	freopen("word.out","w",stdout);
    	n=read();
    	while (scanf("%s",ch)!=EOF)
    	{
    		len=0;sum=0;
    		while (ch[len]=='0'||ch[len]=='1') len++;
    		memset(f,0,sizeof(f));
    		for (int i=len-1;i>=0;i--)
    		{
    			f[i]=f[i+1];
    			if (ch[i+1]=='1')f[i]++;
    		}
    		for (int i=0;i<len;i++)
    		  sum+=(ch[i]=='1')*(i+1);
    		  
    		  
    		  
    		if (sum%(n+1)==0&&len==n) //step 4
    		{
    			for (int i=0;i<len;i++) printf("%c",ch[i]);
    			printf("
    ");
    			continue;
    		}
    		
    		
    		
    		if (len==n) //step 1
    		{
    			bool mrk=0;
    			for (int i=0;i<len;i++)
    			  if (ch[i]=='1'&&(sum-i-1)%(n+1)==0) 
    			  {
    			  	for (int j=0;j<len;j++) 
    			      if (i!=j)printf("%c",ch[j]);
    			      else printf("0");
    			  	printf("
    ");
    			  	mrk=1;break;
    			  }
    			if (mrk) continue;
    		}
    		
    		
    		
    		if (len<n) //step 2
    		{
    			bool mrk=0;
    			for (int i=0;i<=len;i++)
    			  if ((sum+f[i])%(n+1)==0)
    			  {
    			  	 for (int j=0;j<len;j++) 
    			  	 {
    				   printf("%c",ch[j]);
    				   if(i==j) printf("0");
    				 }
    			  	 printf("
    ");
    			  	 mrk=1;break;
    			  }
    			if (mrk) continue;
    			for (int i=0;i<=len;i++)
    			  if ((sum+f[i]+i+1)%(n+1)==0)
    			  {
    			  	for (int j=0;j<len;j++) 
    				  {
    				    printf("%c",ch[j]);
    				  	if (i==j) printf("1");
    				  }
    				printf("
    ");
    				mrk=1;break;
    			  }
    			if (mrk) continue;
    		}
    		
    		
    		
    		if (len>n) //step 3
    		{
    			bool mrk=0;
    			for (int i=0;i<len;i++)
    			  {
    			  	int t=sum-f[i]-(ch[i]=='1')*(i+1);
    			  	if (t%(n+1)==0)
    			  	{
    			  		for (int j=0;j<len;j++)
    			  		  if (i!=j) printf("%c",ch[j]);
    			  		  printf("
    ");
    			  		  mrk=1;break;
    			  	}
    			  }
    			if (mrk) continue;
    		}
    		printf("-1
    ");
    	}
    }
    
    ——by zhber,转载请注明来源
  • 相关阅读:
    BZOJ 1191 HNOI2006 超级英雄hero
    BZOJ 2442 Usaco2011 Open 修建草坪
    BZOJ 1812 IOI 2005 riv
    OJ 1159 holiday
    BZOJ 1491 NOI 2007 社交网络
    NOIP2014 D1 T3
    BZOJ 2423 HAOI 2010 最长公共子序列
    LCA模板
    NOIP 2015 D1T2信息传递
    数据结构
  • 原文地址:https://www.cnblogs.com/zhber/p/4036069.html
Copyright © 2020-2023  润新知