P2724 [IOI 1998 / USACO3.1] 联系 Contact 做题笔记
思路
本题可以暴力枚举解决,但是直接暴力枚举又会超时
怎么办呢,注意到这个序列中只有 \(0\) 和 \(1\),长得像二进制。直接把二进制强压成十进制就不用一位一位的比较了
枚举字符长度(难点) + sort排序 + 输出(坑点)
本题坑点
这题的坑挺多的。。。
USACO的输出规矩真多
-
每输入80个字符换行
-
长度相同按字典序排序
-
行末不能有多余空格,输出开头结尾不能有多余换行
-
出现次数为 \(0\) 的字符串不要输出
代码
思路挺简单的但是蒟蒻的史山码风还是写了100行
不知道为什么这么多代码
#include <bits/stdc++.h>
using namespace std;
struct node
{
int len, data, num;
} qwq[100005];
int a, b, n, s[200005], k, len, qlen, t, now;
char c;
bool cmp(node x, node y)
{
if (x.num != y.num)
{
return x.num > y.num;
}
if (x.len != y.len)
{
return x.len < y.len;
}
return x.data < y.data;
}
void print(int l, int data)
{
for (int i = l - 1; i >= 0; i--)
{
cout << ((data >> i) & 1);
}
}
signed main()
{
cin >> a >> b >> n;
while ((c = getchar()) != EOF)
{
if (c == '0' || c == '1')
{
s[++len] = c - '0';
}
}
for (int m = a; m <= b; m++)
{
int cnt[1 << 12] = {}, sum = 0;
for (int i = 1; i <= m; i++)
{
sum *= 2;
sum += s[i];
}
for (int i = m; i <= len; i++)
{
cnt[sum]++;
if (s[i - m + 1] == 1)
{
sum -= (1 << (m - 1));
}
sum *= 2;
sum += s[i + 1];
}
for (int i = 0; i < (1 << m); i++)
{
if (cnt[i])
{
qwq[++qlen].len = m;
qwq[qlen].num = cnt[i];
qwq[qlen].data = i;
}
}
}
sort(qwq + 1, qwq + qlen + 1, cmp);
while (t < n && now < qlen)
{
t++, now++;
if (t != 1)
{
cout << endl;
}
if(qwq[now].num == 0)
{
break;
}
cout << qwq[now].num << endl;
print(qwq[now].len, qwq[now].data);
int endd = 1;
for (int i = now + 1; i <= qlen; i++)
{
if (qwq[i].num == qwq[now].num)
{
if (endd % 6 != 0)
cout << " ";
print(qwq[i].len, qwq[i].data);
now++, endd++;
if (endd % 6 == 0 && qwq[i + 1].num == qwq[now].num)
{
cout << endl;
}
}
else
{
break;
}
}
}
}

浙公网安备 33010602011771号