M. Function and Function
思路:经过比较小的操作后结果会陷入01循环,所以枚举即可.
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define double long double
#define int long long
#define xiaowen ac
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e6 + 7;
const int P = 131;
/*
https://codeforces.com/gym/104270/problem/M
*/
map<int, int> mp;
int f(int x){
string s = to_string(x);
int ans = 0;
for (int i = 0; i < s.length();i++){
int k = s[i] - '0';
ans += mp[k];
}
return ans;
}
void solve()
{
mp[0] = 1, mp[1] = 0;
mp[2] = 0, mp[3] = 0;
mp[4] = 1, mp[5] = 0;
mp[6] = 1, mp[7] = 0;
mp[8] = 2, mp[9] = 1;
int x, k;
cin >> x >> k;
int res = 0;
while(k--){
x = f(x);
if(x==0){
if(k & 1){
cout << "1" << '\n';
return;
}else {
cout << "0" << '\n';
return;
}
}
}
cout << x << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
//T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
J. Books
思路:当n==m时,直接输出 "Richman".否则统计数组中0的个数,因为这些是不需要付钱就可以获得的,也就是说我要买的书的数量应该大于等于数组中0的个数才符合要求,之后我们再求还需要买 的书的数量,记为k,直接买数组中除0外的前k个,代价为sum,设最后一个买的书的下标为 j,在求 [j+1,n]中的最小值,记为mi,答案就是sum+mi-1.(注意此题不能二分答案)
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define double long double
#define int long long
#define xiaowen ac
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e6 + 7;
const int P = 131;
int n, m;
int a[N];
void solve()
{
cin >> n >> m;
for (int i = 1; i <= n;i++){
cin >> a[i];
}
if(n==m){
cout << "Richman" << '\n';
}else {
int cnt = 0;
for (int i = 1; i <= n;i++){
if(a[i]==0){
cnt++;
}
}
if(cnt > m){
cout << "Impossible" << '\n';
}else {
int k = m - cnt;
int sum = 0;
int mi = 1e18;
for (int i = 1; i <= n;i++){
if(a[i]==0)continue;
if(k > 0){
sum += a[i];
k--;
}else {
mi = min(mi, a[i]);
}
}
cout << (sum + mi - 1) << '\n';
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
// T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
C. Flippy Sequence
思路:分类讨论
先判断初始时s是否等于t ,若s == t,res=(n*(n+1))/2,否则求s 与 t 的异或数组 a[],求a中连续一的个数,记为cnt。先特判n==1的情况,之后当cnt >= 3时,显然无解.当cnt == 2时,发现结果是 6 ,当 cnt == 1时,记1的个数为k,res=(k-1)*2+(n-k)*2. (1贡献的方案数加上0贡献的方案数)
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define double long double
#define int long long
#define xiaowen ac
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e6 + 7;
const int P = 131;
int n;
string s, t;
int a[N];
void solve()
{
cin >> n;
cin >> s;
cin >> t;
// 求 s与t的异或数组
for (int i = 0; i < n;i++){
a[i] = (s[i] - '0') ^ (t[i] - '0');
}
if(s==t){
cout << (n * (n + 1)) / 2 << '\n';
return;
}else {
if(n==1){
// 0 1 或 1 0
cout << "0" << '\n';
return;
}
// 根据连续1的个数进行分类讨论
int cnt = 0;
for (int i = 0; i < n;i++){
if(a[i]==1){
int j = i;
cnt++;
while(j < n && a[j]==1){
j++;
}
i = j - 1;
}
}
if(cnt >= 3){
// 根据鸽笼原理,无解
cout << "0" << '\n';
}else if(cnt == 2){
// 手推发现只有6种情况
cout << "6" << '\n';
}else if(cnt == 1){
int k = 0;// 表示1的个数
for (int i = 0; i < n;i++){
k += (a[i] == 1);
}
int res =(k-1)*2+ (n - k) * 2;
cout << res << '\n';
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
//T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
E. Plants vs. Zombies
思路:二份答案
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define double long double
#define int long long
#define xiaowen ac
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e6 + 7;
const int P = 131;
// 二分答案
int n, m;
int a[N];
int b[N];
bool check(int x){
// 需要边走边更新 b[i]次数可能会因为浇水而减小
for (int i = 0; i <= n + 3;i++){
b[i] = 0;
}
int ans = 0;
for (int i = 1; i <= n;i++){
if(x > b[i]){
int t = x - b[i];
t = (t + a[i] - 1) / a[i];
ans += t * 2 - 1;
if(ans > m){
return false;
}
b[i + 1] += a[i + 1] * (t - 1);
}else {
ans++;
}
}
return true;
}
void solve()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
int res = 0;
int l = 0, r = 1e18;
while (l <= r)
{
int mid = (l + r) / 2;
if (check(mid))
{
l = mid + 1;
res = max(res, mid);
}
else
{
r = mid - 1;
}
}
cout << res << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
// T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
F. Tournament
思路:打表找规律,VP时没写出来
代码:
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define debug(x) cout << "[debug] " #x << " = " << x << '\n';
#define double long double
#define int long long
#define xiaowen ac
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e6 + 7;
const int P = 131;
void solve()
{
int n, k;
cin >> n >> k;
int down = (n & (-n));
if(k >= down){
cout << "Impossible" << '\n';
}else {
for (int i = 1; i <= k;i++){
for (int j = 0; j < n;j++){
if(j != n-1){
cout << ((i ^ j) + 1) << " ";
}else {
cout << ((i ^ j) + 1) << '\n';
}
}
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T;
//T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}