2023.7.8洛谷月赛
洛谷2023.7.8月赛
T1
观察发现合法的数转成二进制只有两种情况。
一种是一个一,这种直接加一输出就好。
一种是两个一,我们手模一下 \(12\) 这种就能发现,直接加上最小的一位一的值就可以得到下一位数,当然有可能两个一是相邻的,这种情况实际上是不会影响答案的。
有个求 popcount 的 STL,WA 了好久才知道只能处理 \(32\) 位。
#include <bits/stdc++.h>
#define int long long
#define N 1000100
using namespace std;
int T, n;
inline int popcount(int x)
{
int ans = 0;
while(x) ans ++, x -= (x & (-x));
return ans;
}
signed main()
{
cin >> T;
while(T --)
{
cin >> n;
int cnt = popcount(n), k = 0;
if(cnt >= 3) {cout << "No,Commander" << endl; continue;}
if(cnt <= 1) {cout << n + 1 << endl; continue;}
if(cnt == 2)
{
while((n & (1ll << k)) == 0) k ++;
cout << (n + (1ll << k)) << endl;
}
}
return 0;
}
T2
就是让你构造一堆操作,解决类似汉诺塔的问题。
我们不难发现可以直接暴力来求,操作数要小于 \(1e6\),但 \(n\le 1300\),所以我们可以尽情发挥。
我们需要开两个栈来模拟题目,首先我们初始都在 A 上,我们通过不断的弹栈入栈把当前不需要的圆盘在 AB 之间移动,当我们找到需要的盘子的时候,直接放进 C 即可,因为最坏就是一个需要挪一堆,最坏其实是 \(1300^{2}\),但想到我们是在 AB 上,我们在从一根挪到另一根的时候,我们可以直接不再挪回来,直接留在那里,然后我们再从这些柱子里找,均摊一下大约最坏 \(\frac{1300^{2}}{2}\)(?
code:
#include <bits/stdc++.h>
#define int long long
#define N 1000100
using namespace std;
int n, cnt, a[N], s[N];//1是A盘上,2是B盘上,3是C盘上
stack<int> q1, q2;
char s1[N], s2[N];
signed main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
cin >> s[i], a[s[i]] = 1;
for(int i = n; i >= 1; i --)
q1.push(s[i]);
for(int i = n; i >= 1; i --)
{
if(a[i] == 1)
{
while(!q1.empty() && q1.top() != i)
{
a[q1.top()] = 2;
q2.push(q1.top());
q1.pop();
s1[++ cnt] = 'A';
s2[cnt] = 'B';
}
a[q1.top()] = 3;
q1.pop();
s1[++ cnt] = 'A';
s2[cnt] = 'C';
}
else if(a[i] == 2)
{
while(!q2.empty() && q2.top() != i)
{
a[q2.top()] = 1;
q1.push(q2.top());
q2.pop();
s1[++ cnt] = 'B';
s2[cnt] = 'A';
}
a[q2.top()] = 3;
q2.pop();
s1[++ cnt] = 'B';
s2[cnt] = 'C';
}
}
cout << cnt << endl;
for (int i = 1; i <= cnt; i ++)
cout << s1[i] << " " << s2[i] << endl;
return 0;
}
T3
考试打了个暴力,思路是直接暴力描述第二个串,然后求所有的个数的 \(\gcd\) 然后一除,就得到了压缩后的第二个串,然后再每次累加串的总长直接匹配,最后判断是不是倍数关系。
特殊性质一比较好打,就是第二个串都是一个字符,直接用前缀和啥的乱搞就行。
特殊性质二就是分成了两段,挂了。。
暴力:
#include <bits/stdc++.h>
#define int long long
#define N 5000100
using namespace std;
int n, m, s1[N], s2[N], a[N], b[N], cnt;
int A[N], B[N], cc, ans, ff1 = 1, ff2 = 1;
int cnt1, cnt2;
inline void js(int cntl, int cntr, int &ans)
{
int k = 0;
while(k * cnt1 <= cntl && k * cnt2 <= cntr) k ++;
ans += (k - 1);
return ;
}
inline void solve1()
{
int len = 0;
for(int i = 1; i <= n; i ++)
A[i] = A[i - 1] + i;
for(int i = 1; i <= n; i ++)
{
if(s1[i] != s1[i - 1])
{
if(s1[i - 1] == s2[1]) ans += A[len];
len = 1;
}
else len ++;
}
if (len && s1[n] == s2[1]) ans += A[len];
cout << ans << endl;
exit(0);
}
inline void solve2()
{
int last = -1, lastcnt = 0, cnt = 1, k = -1;
for(int i = 1; i <= m; i ++)
if(s2[i] != s2[i + 1] && i != m) k = i;
cnt1 = k, cnt2 = m - k;
int xx = __gcd(cnt1, cnt2);
cnt1 /= xx;
cnt2 /= xx;
if(k == -1)exit(0);
for(int i = 2; i <= n; i ++)
{
if(s1[i] != s2[i - 1])
{
if(last == s2[k] && s1[i - 1] == s2[k + 1])
js(lastcnt, cnt, ans);
lastcnt = cnt;
last = s1[i - 1];
cnt = 1;
}
else cnt ++;
}
if(last == s2[k] && s1[n] == s2[k + 1])
js(lastcnt, cnt, ans);
cout << ans << endl;
exit(0);
}
signed main()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++) cin >> s1[i];
for(int i = 1; i <= m; i ++) cin >> s2[i];
for(int i = 1; i <= m; i ++)
{
if(i != 1 && s2[i] != s2[i - 1])
{
ff1 = 0;
if(ff2 == 1) ff2 = 2;
else ff2 = 0;
}
}
if(ff1) solve1();
// if(ff2 == 2) solve2();
for(int i = 1; i <= m; i ++)
{
if(s2[i] != s2[i - 1]) a[++ cnt] = s2[i];
b[cnt] ++;
}
int xx = b[1], len = 0;
for(int i = 2; i <= cnt; i ++) xx = __gcd(xx, b[i]);
for(int i = 1; i <= cnt; i ++) b[i] /= xx, len += b[i];
int nn = len, cao = 1;
while(nn <= n)
{
for(int i = 1; i + nn - 1 <= n; i ++)
{
cc = 0;
for(int o = 1; o <= cnt; o ++) A[o] = B[o] = 0;
int j = i + nn - 1, ff = 1;
int cccc = s1[i - 1];
s1[i - 1] = 1e9;
for(int o = i; o <= j; o ++)
{
if(s1[o] != s1[o - 1]) A[++ cc] = s1[o];
B[cc] ++;
}
if(cc != cnt) {s1[i - 1] = cccc; continue;}
for(int o = 1; o <= cc; o ++)
{
if(A[o] != a[o]) {ff = 0; break;}
if(B[o] / cao != b[o]) {ff = 0; break;}
}
// cout << B[1] << " i :" << i << " DDDD: " << nn << " ff :" << ff << " cao :" << cao << endl;
if(ff) ans ++;
}
nn += len;
cao ++;
}
// for(int i = 1; i <= n; i ++) cout << s1[i] << " "; cout << endl;
cout << ans << endl;
return 0;
}
本文来自博客园,作者:北烛青澜,转载请注明原文链接:https://www.cnblogs.com/Multitree/articles/17537974.html
The heart is higher than the sky, and life is thinner than paper.
浙公网安备 33010602011771号