2022.4.26
Codeforces Global Round 20
A - Log Chopping
看n太小直接用vector暴力模拟了,看题解发现代码十分简洁。
暴力模拟代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
vector<int> que;
void check()
{
while(que.size()&&que.back()==1)
que.pop_back();
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--)
{
que.clear();
int n;
cin>>n;
for (int i = 1; i <= n ;i++)
{
int x;
cin>>x;
que.push_back(x);
}
int f = 0;
while(que.size())
{
check();
if(que.size()==0)
break;
f ^= 1;
int t = que.back();
que.pop_back();
if(t&1)
{
que.push_back(t / 2 + 1);
que.push_back(t / 2 );
}
else
{
que.push_back(t / 2 );
que.push_back(t / 2 );
}
}
if(f)
{
cout << "errorgorn\n";
}
else
cout << "maomao90\n";
}
return 0;
}
正解,发现如果要把一个数全部拆成1则需要x-1次操作。最后相加判断奇偶性即可。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--)
{
int n, f = 0;
cin>>n;
for (int i = 1; i <= n ;i++)
{
int x;
cin>>x;
f += x - 1;
}
if(f&1)
{
cout << "errorgorn\n";
}
else
cout << "maomao90\n";
}
return 0;
}
B - I love AAAB
wa了很多发,最后发现一个很重要的性质,就是任何前缀里a的个数都需要大于等于b的个数,否则无法构造,特判一下第一个字母必须为A,最后一个字母必须为B。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--)
{
string s;
cin >> s;
if(s.length()==1||s[0]=='B'||s[s.length()-1]!='B')
{
cout << "no\n";
continue;
}
int cnta = 0, cntb = 0,f=0;
for (int i = 0; i < s.length();i++)
{
if(s[i]=='A')
{
cnta++;
}
else
cntb++;
if(cnta<cntb)
{
f = 1;
break;
}
}
if(f)
cout << "no\n";
else
cout << "yes\n";
}
return 0;
}
C - Unequal Array
观察发现如果有一堆数是连续且满足a[i]=a[i-1]的话,则有办法让他们的equality为1,操作次数即为区间的长度-1。如 2 1 1 1 1 2。-> 2 1 3 3 1 2。操作次数即为满足a[i]=a[i-1]的i的最大下标和最小下标之差-1.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+10,INF=1e9;
int a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
int n;
cin >> n;
for (int i = 1; i <= n;i++)
{
cin >> a[i];
}
int l = n, r = -1, cnt = 0;
for (int i = 2; i <= n;i++)
{
if(a[i]==a[i-1])
{
cnt++;
l = min(l, i);
r = max(r, i);
}
}
if(cnt<=1)
{
cout << "0\n";
}
else
{
cout << max(1, r - l - 1) << '\n';
}
}
return 0;
}
AtCoder Regular Contest 139
A - Trailing Zeros
一开始想到用位运算是对的,但是后面搞着搞着思路错了于是换了字符串写就陷入了麻烦。看了别人的代码,思路是从后往前先让前a[i]个位为0,如果下一位为0就将这一位变成1,否则寻找下一个0将它变成1即可。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int a[70];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, x, pos = 1;
cin>>n;
for (int i = 1; i <= n;i++)
{
cin >> x;
for (int j = 0; j <= x;j++)
{
a[j] = 0;
}
if(a[x+1]==0)
{
a[x + 1] = 1;
continue;
}
for (int i = x + 2; i <= 63;i++)
{
if(a[i]==0)
{
a[i] = 1;
break;
}
else
a[i] = 0;
}
}
ll ans = 0;
for (int i = 1; i <= 63;i++)
{
ans = ans + a[i] * pow(2,i-1);
}
cout << ans;
return 0;
}
B - Make N
想到了一半思路,就是比较三种情况的单价,如果1的单价最小显然我们直接n*x就完事了,否则需要比较第二和第三种的单价,假设第二种的单价最小,则其有n/a次,第三种最多为a-1次,如果为a次我们可以用第二种操作来代替,于是我们比较哪个更小,枚举次数从而求最小值,我是在这个地方思路错了,没有枚举而直接全部除了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
ll n ,a, b, x, y, z;
cin >> n >> a >> b >> x >> y >> z;
ll ans = 1e18;
if(a*x<=y&&b*x<=z)
{
cout << n * x <<'\n';
continue;
}
else if(a*z<b*y)
{
swap(a, b);
swap(y, z);
}
if(n/a<=a-1)
{
for (int i = 0; i <= n / a;i++)
{
ll t = n - i * a;
ans = min(ans, i * y + (t / b) * z + (t % b) * x);
}
}
else
{
for (int i = 0; i <= min(n/b,a - 1);i++)
{
ll t = n - i * b;
ans = min(ans, i * z + (t / a) * y + (t % a) * x);
}
}
cout << ans << '\n';
}
return 0;
}