(0条未读通知) 牛客小白月赛77_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com)
题目理解:这里连成环相当于拿一个数其对应下标的位置则为数的位置将其连成环,需要递增则相当于需要自环
每操作一次就会多出来一个自环相当于此时的m就会+
代码:
#include
using namespace std;
int n, m;
int main()
{
cin >> n >> m;
cout << n - m;
return 0;
}
此题可以进行模拟,将当前商品的所在货架和应在货架统计出来,循环货架,统计开始在当前货架的商品,这些商品是需要加到购物车中的,当然如果说这里的商品本身就是最终位置将其减去即可。统计需要挪动商品的最大值,将其上取整(mx - 1) / k + 1即可计算出次数
#include
using namespace std;
const int N = 1000005;
int n, m, k, s, e, res, mx, st[N], ed[N];
int main()
{
cin >> n >> m >> k;
for(int i = 1; i <= m; i ++)
{
cin >> s >> e;
st[s] ++;
ed[e] ++;
}
for(int i = 1; i <= n; i ++)
{
res += st[i];
res -= ed[i];
mx = max(mx, res);
}
cout << (mx - 1) / k + 1;
return 0;
}
使用substr会超时,故使用字符串哈希,但是需要记录上一次哈希到相同子串的位置来避免重复
比如这样一组输入
7 4 2
1231231
显然正确输出是0,但是如果不对每一次哈希到这个串的位置标记就会导致记录了不该记录的子串
例如 1231 会记录两次
那我们就可以记录第一次1231的位置,如果下一次1231出现,和前一次1231出现的位置重叠了,那么肯定就不合法了
因为第一个1231出现后被删去就只剩下231 就没有第二个1231了
字符串hash模板:
#include
using namespace std;
typedef unsigned long long ULL;
const int N = 1e6 + 10;
const int P = 131;
ULL p[N], h[N];
char s[N];
map cnt;
map last;
int n, m, k, ans;
//预处理hash函数的前缀和
void init()
{
p[0] = 1;
for(int i = 1; i <= n; i ++)
{
p[i] = p[i - 1] * P;
h[i] = h[i - 1] * P + s[i];
}
}
//计算s[l~r]的hash值
ULL get(int l, int r)
{
return h[r] - h[l - 1] * p[r - l + 1];
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m >> k >> s + 1;
init();
for(int i = 1; i <= n; i ++)
{
if(i + m - 1 > n)break;
ULL x = get(i, i + m - 1);
if(last[x] + m - 1 >= i && last[x])continue;
cnt[x] ++;
last[x] = i;
}
for(auto i : cnt)
{
if(i.second == k)ans ++;
}
cout << ans;
return 0;
}
由于题目所给数据可以观察用简单bfs无法通过,由于a * a这样计算可能会超范围,所以从b开始每次开根号即可,开根,除二,以及减一
解释:
eg.13: 需要执行 -1,然后 / 2,代码中的 + 1相当于/ 2的操作,然后用z.x - y - y算出多的呢部分需要执行的操作,如这里知道了需要执行-1操作,因为13 - 6 - 6 = 1
#include
using namespace std;
typedef long long ll;
struct node
{
ll x, y;
};
void solve()
{
ll ans = 1e12;
ll a, b;
cin >> a >> b;
if(a == b)ans = 0;
else
{
queue q;
q.push({b, 0});
while(!q.empty())
{
node z = q.front();
q.pop();
ll x = sqrt(z.x),
y = z.x >> 1;
if(z.x <= a)continue;
if(x >= a)
{
ll res = z.y + z.x - x * x + 1;
if(x == a)ans = min(ans, res);
else q.push({x, res});
}
if(y >= a)
{
ll res = z.y + z.x - y - y + 1;
if(y == a)ans = min(ans, res);
else q.push({y, res});
}
if(y < a)
{
ll res = z.y + z.x - a;
ans = min(ans, res);
}
}
}
cout << ans << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
ll t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}