您的位置:首页 > 大数据 > 人工智能

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

2018-09-11 21:50 363 查看

 题目传送门

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

(不,还是我太弱了。)

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

开始想的是枚举每个长度的串,然后把这个二进制转为十进制的哈希值,用桶来记录一下。但很快就会发现,可能有很多个前导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

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: