A. Spring Couplets
很明显的一个签到题,题面废话比较多,大意就是:
给你一个n,有两行输入,每一行有n个字符串,每个字符串后面都有一个数字
1.每行的最后一个字符串的数字一定要小于等于2,第二行的的最后一个字符串的数字要严格大于2
2.上下第i个位置字符串后面的数字的数字要相反,不能同时小于等于2或者严格大于2
#include <bits/stdc++.h>
using namespace std;
#define int long long
string a[29], b[29];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
for (int i = 1; i <= n; i++)
{
int x = (a[i][a[i].size() - 1] - '0');
int y = (b[i][b[i].size() - 1] - '0');
if (x <= 2)
{
if (y <= 2)
{
puts("NO");
return;
}
}
else
{
if (y > 2)
{
puts("NO");
return;
}
}
}
int x = (a[n][a[n].size() - 1] - '0');
int y = (b[n][b[n].size() - 1] - '0');
if (x <= 2 || y > 2)
{
puts("NO");
return;
}
puts("YES");
return;
}
signed main()
{
int t;
for (cin >> t; t; t--)
solve();
}
I. Fake Walsh Transform
签到题,主要是找规律,也是一个结论,从0到2的n次方-1,全部异或起来等于0,其中去掉那个数字,异或结果就是几
比如:
0⊕1⊕2⊕4=3
0⊕1⊕2⊕3⊕4⊕5⊕7=6
0⊕1⊕2⊕4⊕5⊕6⊕7=3
还有几个特殊情况,判掉就好了
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
int m, n;
cin >> m >> n;
int ans = pow(2, m);
if (m == 1 && n == 0)
{
cout << ans - 1 << endl;
return;
}
if (n == 0 || m == 1)
cout << ans << endl;
else
cout << ans - 1 << endl;
}
signed main()
{
int t;
for (cin >> t; t; t--)
solve();
}
K. Longest Continuous 1
是一个思维类的签到题,其实多手摸几组数据就发现了,最长的1出现的位置一定是,2的n次方减一到2的n次方的位置
比如:
0
10
11
100
101
110
111
1000
最长的是7到8的连接位置 111 1000,从这里到下一个2的次方的时候,4都是最大的,所以只要确定从2的0次方开始累加,累加到多少可以大于长度n,就可以了
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
string a[29], b[29];
int ksm(int n, int m)
{
int ans = 1;
while (m)
{
if (m & 1)
{
ans *= n;
}
n *= n;
m >>= 1;
}
return ans;
}
void solve()
{
int n;
cin >> n;
if (n <= 2)
{
if (n == 2)
cout << 1 << endl;
else if (n == 1)
cout << "0" << endl;
return;
}
n -= 1;
int sum = 0;
int cnt = 0;
while (sum < n)
{
sum += ksm(2, cnt) * (cnt + 1);
cnt++;
// cout << " " << sum << endl;
}
cout << cnt << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
for (cin >> t; t; t--)
solve();
}
C. Magical Rearrangement
给出数字0 ~ 9每一个的个数,用完所给的全部数字组成一个任意两个相邻数字都不相等的最小的数字字符串。
主要思路是贪心+排序:
从高位开始贪心,用两个容器维护用过的数的数量和用过的最多的数量,然后用小到大去枚举
贴上队友的代码
#include <bits/stdc++.h>
#define buff \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
#define endl "\n"
using namespace std;
const int N = 1e5 + 9;
int a[N];
int tofind(int last)
{
for (int i = 0; i <= 9; i++)
{
if (!a[i] || i == last)
continue;
a[i]--;
int idx = 0, tt = 0;
for (int j = 0; j <= 9; j++)
{
tt += a[j];
if (a[j] > a[idx])
{
idx = j;
}
}
tt -= a[idx];
if ((idx == i && a[idx] >= tt + 1) || (idx != i && a[idx] > tt + 1))
a[i]++;
else
return i;
}
return -1;
}
void solve()
{
int mx = 0;
int otr = 0;
bool zero = 0;
for (int i = 0; i <= 9; i++)
{
cin >> a[i];
otr += a[i];
if (mx < a[i])
{
mx = a[i];
if (i == 0)
zero = 1;
else
zero = 0;
}
}
otr -= mx;
if(otr ==0 && a[0] == 1)
{
cout << 0 << endl;
return ;
}
if (zero)
{
if (mx >= otr + 1)
{
cout << -1 << endl;
return;
}
}
else
{
if (mx > otr + 1)
{
cout << -1 << endl;
return;
}
}
int x = tofind(0);
while (x >= 0)
{
cout << x;
x = tofind(x);
}
cout << endl;
}
int main()
{
// buff;
int t;
cin >> t;
while (t--)
solve();
}