USACO Training3.1联系【排序终极题目】By cellur925

 题目传送门

这题我们很容易想到直接枚举即可。算法本身并没有什么难度但是细节超多!于是这题整整卡了一天.......

(不,还是我太弱了。)

期间还暴露出一些平时没有特别注意的问题,这次一起解决。

开始想的是枚举每个长度的串,然后把这个二进制转为十进制的哈希值,用桶来记录一下。但很快就会发现,可能有很多个前导0.譬如说01与001与0001都是不一样的。

那么我们怎么做呢?可以用map映射。也不要转什么哈希值了,直接建立从string到int的映射。(建立方法:如果在map表中出现,对应的桶直接计数器加一;否则没出现(map值为0)则新开)。

另外,我们完全没有必要把串都读入后再统一枚举,而可以边读入边枚举串。

然后输出也是很恶心的....最后抄redbag的了

那些小问题写在代码里。

Code

  1 /*
  2 ID:cellur_2
  3 TASK:contact
  4 LANG:C++
  5 */
  6 #include<cstdio>
  7 #include<algorithm>
  8 #include<map>
  9 #include<iostream>//string类型在iostream库里 
 10 
 11 using namespace std;
 12 
 13 map<string,int>m;
 14 int n,A,B,res,len;
 15 char ch,seq[500000];//不是200 qwq  读错题。 
 16 struct node{
 17     string str;
 18     int tong;
 19 }p[500000];
 20 
 21 bool cmp(node x,node y)
 22 {
 23     if(x.tong==y.tong)
 24     {
 25         if(x.str.size()==y.str.size())
 26             return x.str<y.str;
 27         return x.str.size()<y.str.size();
 28     }
 29     return x.tong>y.tong;
 30 }
 31 
 32 int main()
 33 {
 34     freopen("contact.in","r",stdin);
 35     freopen("contact.out","w",stdout);
 36     scanf("%d%d%d",&A,&B,&n);//输入顺序错了yyy 
 37     while((ch=getchar())!=EOF)//这里竟然要加括号。
 38     {
 39         if(ch=='1'||ch=='0')
 40         {
 41             seq[++len]=ch;
 42             string tmp="";//string加值不能为空 而且要双引号
 43             int lim=max(1,len-B+1);
 44             for(int i=len;i>=lim;i--)
 45             {
 46                 tmp=seq[i]+tmp;//必须这样写
 47                 //是有严格先后顺序的 否则不对 
 48                 if(len-i+1>=A)
 49                 {
 50                     if(m[tmp]==0)//用map 从未出现
 51                     {
 52                         m[tmp]=++res;
 53                         p[m[tmp]].str=tmp;
 54                     }
 55                     p[m[tmp]].tong++; 
 56                 }
 57             } 
 58         }
 59     } 
 60     sort(p+1,p+res+1,cmp);
 61 //    for(int i=1;i<=res;i++) printf("%d\n",p[i].tong);
 62 /*    while(n--)
 63     {
 64         printf("%d\n",p[pos].tong);
 65         int fake=0,pre=pos;
 66     //    cout<<pre<<"@@@";
 67         while(p[pos].tong==p[pos+1].tong)
 68             pos++;
 69         for(int i=pre;i<=pos;i++)
 70         {
 71             fake++;
 72             if(fake>6) printf("\n"),fake=0;
 73             cout<<p[i].str<<" ";
 74         }
 75         if(pos==pre) pos++; 
 76         printf("\n");
 77     }
 78     之前自己写的输出 但是用while控制就会出现死循环。
 79     比如数据2:
 80     1 4 10
 81     1
 82     在我写的之下可能会陷入死循环。 
 83     */
 84     int xx=0;
 85     for (int i=1;i<=res;i++)
 86     {
 87         if (n==0&&p[i].tong!=p[i-1].tong) break;
 88         if (p[i].tong==p[i-1].tong)
 89         {
 90             if (xx%6==0) cout<<p[i].str; 
 91             else cout<<" "<<p[i].str; 
 92             xx++;
 93             if (xx%6==0) printf("\n");
 94         }
 95         else
 96         {
 97             n--; 
 98             if (i!=1&&xx%6!=0) printf("\n");
 99             printf("%d\n",p[i].tong); 
100             cout<<p[i].str; 
101             xx=1; 
102         }
103     } 
104     if (xx%6!=0) printf("\n");
105     return 0;
106 }
View Code

猜你喜欢

转载自www.cnblogs.com/nopartyfoucaodong/p/9630599.html
今日推荐