题目出自:Codeforces Round #547 (Div. 3)
A. Game 23
https://codeforces.com/problemset/problem/1141/A
#include
using namespace std;
typedef long long ll;
ll n, m;
bool flag;
int cnt;
//数据不大,暴力深搜
void dfs(int now, int step) {
if (now == m) {
flag = true;
cnt = step;
return;
}
if (now > m)return;
dfs(now * 2, step + 1);
dfs(now * 3, step + 1);
}
int main() {
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0);
cin >> n >> m;
dfs(n, 0);
if (flag)cout << cnt << endl;
else cout << -1 << endl;
}
B. Maximal Continuous Rest
https://codeforces.com/problemset/problem/1141/B
作两个周期大小,最大连续序列
#include
using namespace std;
const int N = 4e5 + 50;
int n, a[N];
int main() {
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0);
cin >> n; bool flag = true;
for (int i = 0; i < n; ++i) {
cin >> a[i];
if (a[i] != 0)flag = false;
}
if (flag)return cout << 0, 0;
for (int i = n; i < 2 * n; i++) a[i] = a[i - n];
int cnt = 0, msum = 0;
for (int i = 0; i < 2 * n; i++){
if (a[i] == 1 && a[i + 1] == 1)
cnt++;
if (cnt > msum)
msum = cnt;
if (a[i] == 0)
cnt = 1;
}
cout << msum << endl;
}
C. Polycarp Restores Permutation
https://codeforces.com/problemset/problem/1141/C
做的时候用推导出数学公式但没做特判,导致WA
WA代码:
#include
using namespace std;
const int N = 4e5 + 50;
int n, a[N];
int main() {
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0);
cin >> n; bool flag = true;
for (int i = 0; i < n; ++i) {
cin >> a[i];
if (a[i] != 0)flag = false;
}
if (flag)return cout << 0, 0;
for (int i = n; i < 2 * n; i++) a[i] = a[i - n];
int cnt = 0, msum = 0;
for (int i = 0; i < 2 * n; i++){
if (a[i] == 1 && a[i + 1] == 1)
cnt++;
if (cnt > msum)
msum = cnt;
if (a[i] == 0)
cnt = 1;
}
cout << msum << endl;
}
另一种思路
另p数组首个为0.求出p数组,再得到p数组中最小的值,将p中所有数减掉最小值再加1得到原p。
同时记录原p中每个数出现的次数。超过一次,说明不能还原 。
#include
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 10;
LL a[MAXN];
map b;
int main(){
int n, v;
cin >> n;
a[0] = 0;
LL sum = 0, mmin = 0;
for (int i = 2;i <= n;i++){
cin >> v;
a[i] = a[i - 1] + v;
sum += a[i];
mmin = min(mmin, a[i]);
}
for (int i = 1;i <= n;i++){
a[i] = a[i] - mmin + 1;
if (b[a[i]] == 1 || a[i] > n) {
cout << -1 << endl;
return 0;
}
b[a[i]] = 1;
}
for (int i = 1;i <= n;i++)
cout << a[i] << ' ' ;
cout << endl;
return 0;
}
使用set容器
#include
using namespace std;
int64_t n, m, mx, i, x, p[222000];
set s;
int main(){
cin >> n;
s.insert(0);
for (i = 1; i < n; i++){
cin >> x;
p[i] = p[i - 1] + x;
m = min(m, p[i]);
mx = max(mx, p[i]);
s.insert(p[i]);
}
if (mx - m != n - 1 || s.size() < n)cout << -1;
else for (i = 0; i < n; i++)cout << p[i] + 1 - m << " ";
}
D. Colored Boots
没有做出来,感觉可以二分图做。
https://codeforces.com/problemset/problem/1141/D
贴上dalao题解
思路:
找到所有小写字母,将它们所有的下标位置存入一个数组,然后每次查询相同的字母在s1,s2中的相同字母的位置,
然后输出就好了。
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 2e5+10;
char s1[maxn],s2[maxn];
vector v1[30],v2[30];
vector > ans;
int main(void)
{
int n,i,j,cnt = 0;
scanf("%d",&n);
scanf("%s%s",s1+1,s2+1);
for(i=1;i<=n;i++){
if(s1[i]>='a'&&s1[i]<='z') v1[s1[i]-'a'].push_back(i);
else v1[26].push_back(i);
if(s2[i]>='a'&&s2[i]<='z') v2[s2[i]-'a'].push_back(i);
else v2[26].push_back(i);
}
for(i=0;i<=26;i++){
while(v1[i].size()>0&&v2[i].size()>0){
ans.push_back(make_pair(v1[i][v1[i].size()-1],v2[i][v2[i].size()-1]));
v1[i].pop_back();
v2[i].pop_back();cnt++;
}
while(v1[i].size()>0&&v2[26].size()>0){
ans.push_back(make_pair(v1[i][v1[i].size()-1],v2[26][v2[26].size()-1]));
v1[i].pop_back();
v2[26].pop_back();cnt++;
}
while(v1[26].size()>0&&v2[i].size()>0){
ans.push_back(make_pair(v1[26][v1[26].size()-1],v2[i][v2[i].size()-1]));
v1[26].pop_back();
v2[i].pop_back();cnt++;
}
}
printf("%d\n",cnt);
for(i=0;i
E. Superhero Battle
https://codeforces.com/problemset/problem/1141/E
题意:
有一个怪兽,初始血量为HHH,他的血量变化情况是一个长度为nnn轮的周期。问怪兽会在第几轮死去。
做法
首先如果怪兽血量在一个周期内不曾小于等于000而且每个周期之后怪兽血量增加,直接输出−1。
之后要知道,怪兽在某个完整的周期之前到达x血量,怪兽就撑不过这轮。
这个 \(x\) 的求法就是遍历一遍周期,找到某个时刻怪兽血量消耗最多。
之后就假设怪兽初始血量为 \(H−x\) 看怪兽能撑过几个完整的轮,设这里轮数为 \(k\) ,每轮怪兽血量减少 \(sum\) ,则要满足
所以不等式右面要上取整得到 \(k\) ,之后再 \(O(n)\) 的进行一个周期看怪兽在第几轮死即可。
#include
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 100;
ll a[maxn];
int main() {
int flag = 0, mark;
ll h, n, sum = 0, mi = inf;
cin >> h >> n;
ll g = h;
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum += a[i];
mi = min(mi, sum);
g += a[i];
if (g <= 0 && !flag) mark = i, flag = 1;
}
if (flag) return cout << mark << endl, 0;
if (sum >= 0) return cout << -1 << endl, 0;
sum = -sum;
h += mi;
ll ans = h / sum * n;
ll cur = h % sum - mi;
while (cur > 0) {
for (int i = 1; i <= n; i++) {
cur += a[i];
ans++;
if (cur <= 0) break;
}
}
printf("%lld\n", ans);
return 0;
}