A - Long Loong
模拟
// Problem: A - Long Loong
// Contest: AtCoder - AtCoder Beginner Contest 336
// URL: https://atcoder.jp/contests/abc336/tasks/abc336_a
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve()
{cin >> n;string s = "";s += 'L';for(int i = 0 ; i < n ; i ++){s += 'o';}s += "ng";cout << s;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;
// cin>>t;while(t--){solve();}return 0;
}
B - CTZ
还是模拟
// Problem: B - CTZ
// Contest: AtCoder - AtCoder Beginner Contest 336
// URL: https://atcoder.jp/contests/abc336/tasks/abc336_b
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve()
{int ans = 0;cin >> n;while(n){if(n & 1)break;elseans++;n/=2;} cout << ans;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;//cin>>t;while(t--){solve();}return 0;
}
C - Even Digits
找出由0 , 2 , 4 , 6 , 8 组成的第x大数,模拟(注意一开始不能取0 , 因此其实是一个开头为4,其余都是5的进制数)。
// Problem: C - Even Digits
// Contest: AtCoder - AtCoder Beginner Contest 336
// URL: https://atcoder.jp/contests/abc336/tasks/abc336_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
int mask[5] = {0 , 2 , 4 , 6 , 8};
void solve()
{LL n;cin >> n;n--;LL k = 1;while(k * 5 <= n){k *= 5;}while(k > 0){int t = n / k;cout << mask[t];n -= t * k;k /= 5;}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;//cin>>t;while(t--){solve();}return 0;
}
D - Pyramid
定义为长度为的好序列,现给定一组数组,你可以选中其子序列,同时将其中的数减去若干,组成一组好序列。求好序列的最大长度。
二分求长度,从头开始遍历,然后判断能否形成这个好序列,首先从头到尾尽可能的组成一组好序列,若到某个数时无法和前面的数组成好序列,那就将这个数变成新序列的第位,其中为这个数的值,这样做必然是最优的。
// Problem: D - Pyramid
// Contest: AtCoder - AtCoder Beginner Contest 336
// URL: https://atcoder.jp/contests/abc336/tasks/abc336_d
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve()
{int n;cin >> n;for(int i = 0 ; i < n ; i ++){cin >> a[i];} int l = 1 , r = (n + 1) / 2;auto check = [&] (int len){int cnt = 0;for(int i = 0 ; i < n ; i ++){if(cnt < len){if(a[i] >= cnt + 1){cnt++;}else{cnt = a[i];}}else{if(a[i] >= len - (cnt - len + 1)){cnt++;}else{cnt = a[i];}}if(cnt >= len * 2 - 1){return true;}}return false;};while(l < r){int mid = (l + r + 1) / 2;if(check(mid)){l = mid;}else{r = mid - 1;}}cout << l << endl;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;
// cin>>t;while(t--){solve();}return 0;
}
E - Digit Sum Divisible
题意:从1~N,输出其中各个位数之和能够整除其的数量。
思路:数位DP,首先可以发现,因此位数之和应当小于。所以我们可以钦定位数和,然后求出每个位数和分别有多少个数满足条件。
定义代表了数的前位,各个位数之和为,余数为的和。其中表示是否为上界(其中0代表未达到上界,1代表还处于上界之中)。每一轮都是将新的数插入之前数的最后,假设加的数为,那么新的余数就变成了 模上位数和。最终答案加上第N的位数位,总和为钦定的位数和,余数为0,状态为0或者1的总数。
// Problem: E - Digit Sum Divisible
// Contest: AtCoder - AtCoder Beginner Contest 336
// URL: https://atcoder.jp/contests/abc336/tasks/abc336_e
// Memory Limit: 1024 MB
// Time Limit: 10000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
#define int long long
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
int dp[20][200][200][2];//第i位,和为x,余数为y的个数,是否为上界的情况
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve()
{string n;cin >> n;int len = n.size();LL ans = 0;for(int i = 1 ; i <= 9 * 14 ; i ++){//钦定位数和memset(dp , 0 , sizeof dp);dp[0][0][0][1] = 1;for(int j = 1 ; j <= len ; j ++){//14for(int k = 0 ; k <= 9 * 14 ; k ++){//总和100for(int num = 0 ; num <= 9 ; num ++){if(k + num > i){continue;}for(int st = 0 ; st < 2 ; st ++){if(st && num > (n[j - 1] - '0')){continue;}for(int res = 0 ; res < i ; res ++){int now_res = (res * 10 + num) % i;dp[j][k + num][now_res][(st && (num == n[j - 1] - '0'))] += dp[j - 1][k][res][st];}}}} }ans += dp[len][i][0][0] + dp[len][i][0][1];}cout <<ans;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;
// cin>>t;while(t--){solve();}return 0;
}
F - Rotation Puzzle
题意:给定一个长为,宽为的二维数组,其中每次操作能够将长为,宽为的块翻转180°。求最终能否变成一个1,2,3,4,5....的顺序数组。限定操作最多为20次。
参考图片
思路:(折半搜索)首先肯定考虑DFS遍历所有情况,然后每一轮的情况共有4种,那么总共的复杂度为肯定是超的。因此考虑从头开始dfs和从尾开始dfs,这样两次dfs的时间复杂度均为 ,然后若有重复的,那么就代表能够从头走到尾,记录一下答案即可。单纯考察折半搜索,就是写起来比较复杂
// Problem: F - Rotation Puzzle
// Contest: AtCoder - AtCoder Beginner Contest 336
// URL: https://atcoder.jp/contests/abc336/tasks/abc336_f
// Memory Limit: 1024 MB
// Time Limit: 5000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
int ans = 25;
map< vector<vector<int>> , int > mp;
vector<vector<int>>s(9 , vector<int>(9 , 0));
void change(int l_min , int l_max ,int r_min , int r_max){for(int i = 0 ; i <= (r_max - r_min) ; i ++){int st = r_min + i;int en = r_max - i;if(st > en)break;else if(st == en){for(int j = 0 ; j <= (l_max - l_min) ; j ++){int ss = l_min + j;int ee = l_max - j;if(ss > ee)break;swap(s[st][ss] , s[en][ee]);} }else{for(int j = 0 ; j <= (l_max - l_min) ; j ++){int ss = l_min + j;int ee = l_max - j;swap(s[st][ss] , s[en][ee]);}}}
}
void dfs(int step){if(step > 10)return;if(!mp.count(s)){mp[s] = step;}else{mp[s] = min(mp[s] , step);}change(0 , n - 2 , 0 , m - 2);dfs(step + 1);change(0 , n - 2 , 0 , m - 2);change(1 , n - 1 , 0 , m - 2);dfs(step + 1);change(1 , n - 1 , 0 , m - 2);change(0 , n - 2 , 1 , m - 1);dfs(step + 1);change(0 , n - 2 , 1 , m - 1);change(1 , n - 1 , 1 , m - 1);dfs(step + 1);change(1 , n - 1 , 1 , m - 1);
}
void dfs2(int step){if(step > 10)return;if(mp.count(s)){ans = min(ans , step + mp[s]);}change(0 , n - 2 , 0 , m - 2);dfs2(step + 1);change(0 , n - 2 , 0 , m - 2);change(1 , n - 1 , 0 , m - 2);dfs2(step + 1);change(1 , n - 1 , 0 , m - 2);change(0 , n - 2 , 1 , m - 1);dfs2(step + 1);change(0 , n - 2 , 1 , m - 1); change(1 , n - 1 , 1 , m - 1);dfs2(step + 1);change(1 , n - 1 , 1 , m - 1);
}
void solve()
{cin >> m >> n;int id = 1;for(int i = 0 ; i < m ; i ++){for(int j = 0 ; j <n ; j ++){cin >> s[i][j];}}dfs(0);id = 1;for(int i = 0 ; i < m ; i ++){for(int j = 0 ; j < n ; j ++){s[i][j] = id++;}}dfs2(0);if(ans == 25)cout << -1;elsecout << ans;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;//cin>>t;while(t--){solve();}return 0;
}