codeforces竞赛1141题解
竞赛链接:http://codeforces.com/contest/1141
A. Game 23
题目大意:
对于两个数n,m,求n通过乘2或者乘3变成m所需要的次数。无解输出-1.
例如120 51840需要7次变换。
解题思路:
如果m%n不等于0,则无解。
如果n>m,则无解。
那么n到达m需要乘的步长为p = m / n,这个如果这个p能被2 3全部整除,则说明有解,否则无解。
AC代码:
//
// Created by jal on 2019-05-21.
//#include <bits/stdc++.h>
using namespace std;
int main(){int n, m;cin >> n >> m;if(n > m || m % n){cout << -1 << endl;return 0;}int p = m / n;int cnt = 0;while(p%2==0){cnt++;p/=2;}while(p%3==0){cnt++;p/=3;}if(p==1){cout << cnt << endl;}else{cout << -1 << endl;}
}
B. Maximal Continuous Rest
题目大意:
长度为n的01数组(至少包含一个0),这个数组序列会不断重复下去。求最长的连续1的个数。
解题思路:
考虑到数组的首尾元素都是1的话,最后的一个元素是与这个数组下一次的第一个元素拼接,所以索性将数组扩大为长度为2*n的,后一半的数组内容同前一半。然后求最长的1的个数即可。
AC代码:
//
// Created by jal on 2019-05-21.
//#include <bits/stdc++.h>
using namespace std;
int main(){int n;cin >> n;vector<int>v(2*n);for(int i = 0; i < n; i++){cin >> v[i];v[n+i] = v[i];}int cnt = 0;int res = 0;for(int i = 1; i < 2 * n; i++){if(v[i] == 0){cnt = 0;}else{if(v[i] == v[i-1]){cnt++;}else{cnt=1;}}res = max(res, cnt);}cout << res << endl;
}
C. Polycarp Restores Permutation
题目大意:
一个n的排列p1,p2,...,pnp_{1},p_{2}, ..., p_{n}p1,p2,...,pn进行差分后得到q1,q2,...,qn−1q_{1}, q_{2} ,... ,q_{n-1}q1,q2,...,qn−1,现在给出数字n和差分序列q1,q2,...,qn−1q_{1}, q_{2} ,... ,q_{n-1}q1,q2,...,qn−1,求出原排列p1,p2,...,pnp_{1},p_{2}, ..., p_{n}p1,p2,...,pn
解题思路:
- 第一种方法O(Nlog(N))O(Nlog(N))O(Nlog(N)):
由于差分序列只有n-1个数,那我们可以在1~n范围内二分枚举排列中的第一个元素p1p_{1}p1,然后通过第一个元素和差分序列就可以在线性时间复杂度内求出排列的其他所有元素。至于为什么可以二分枚举呢, 因为我们所求的所有排列元素的和S是相对p1p_{1}p1单调递增的,所以可以二分。当S=n∗(n+1)/2S=n*(n+1)/2S=n∗(n+1)/2的时候,说明此时的p1p_{1}p1就是正解,二分结束。一直到最后都找不到的话,则无解。 - 第二种方法O(N)O(N)O(N):
递推法直接求出p1p_{1}p1,因为p1=p1,p2=q1+p1,p3=q2+q1+p1,...,pn=qn−1+qn−1+...+q1+p1p_1=p_1, p_2=q_1+p_1,p_3=q_2+q_1+p_1,...,p_n=q_{n-1}+q_{n-1}+...+q_1+p_1p1=p1,p2=q1+p1,p3=q2+q1+p1,...,pn=qn−1+qn−1+...+q1+p1,而排列的和是n∗(n+1)/2n*(n+1)/2n∗(n+1)/2,所以累加所有的PiP_iPi可以得出等式:n∗p1+(n−1)∗q1+(n−2)∗q2+...+1∗qn−1=n∗(n+1)/2{n*p_1+(n-1)*q_1+(n-2)*q_2}+...+1*q_{n-1} = n*(n+1)/2n∗p1+(n−1)∗q1+(n−2)∗q2+...+1∗qn−1=n∗(n+1)/2
因此可以求出P1P_1P1,通过P1P_1P1和差分序列就可以在线性时间复杂度内求出排列的其他所有元素。
注意:
- 上面两种方法都可以AC,不过需要注意的是,本题数据量会达到64位整数,所以变量要定义成long long类型。n∗(n+1)/2n*(n+1)/2n∗(n+1)/2可能会溢出int,所以要写成1LL∗n∗(n+1)/21LL*n*(n+1)/21LL∗n∗(n+1)/2。
- 要判断生成的排列是否合理。也就是生成的序列是不是一个排列,如果不是则输出-1.
AC代码:
- 第一种方法O(Nlog(N))O(Nlog(N))O(Nlog(N)):
//
// Created by jal on 2019-05-21.
//#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main(){// ifstream cin("input.txt");int n;cin >> n;LL s1 = 1LL*n * (n+1)/2;vector<LL>p(n),q(n-1);for(auto &i : q){cin >> i;}int flag = 0;int left = 1, right = n;while(left <= right){p[0] = (left + right )>>1;LL sum = p[0];for(int i = 1; i < n; i++){p[i] = p[i-1] + q[i-1];sum += p[i];}if(sum == s1){flag = 1;map<int,int>mp;for(auto i:p){mp[i]++;}for(int i = 1; i <= n; i++){if(mp[i] != 1){flag = 0;break;}}if(flag){for(auto i: p){cout << i << " ";}cout << endl;}break;}if(sum > s1){right = p[0]-1;}else{left = p[0]+1;}}if(flag == 0){cout << -1 << endl;}
}
- 第二种方法O(N)O(N)O(N):
//
// Created by jal on 2019-05-21.
//#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main(){// ifstream cin("input.txt");int n;cin >> n;vector<int>d(n-1);for(int i = 0; i < n-1; i++){cin >> d[i];}vector<int>a(n);LL s = 1LL*n * (n+1)/2;for(int i = 1; i < n; i++){s -= 1LL * i * d[n-i-1];}map<int, int>mp;a[0] = s / n;mp[a[0]] = 1;LL sum = a[0];for(int i = 1; i < n; i++){a[i] = a[i-1] + d[i-1];mp[a[i]]++;sum += a[i];}int flag = 1;for(int i = 1; i <= n; i++){if(mp[i] != 1){flag = 0;break;}}if(flag){for(auto i : a){cout << i << " ";}cout <<endl;}else{cout << -1 << endl;}
}
D. Colored Boots
题目大意:
给出两个长度为n的字符串,只有小写字母和问号,相同的小写字母可以匹配,问号可以跟任意小写字母和问号匹配。求最大的匹配的对数,并且输出下标。每个字母不可以被二次匹配。
解题思路:
每个小写字母和问号都关联一个链表,初始时将每次字母和问号所在的下标存到对应字符的链表里。然后先匹配小写字母,小写字母无法与小写字母匹配,就与问号匹配,最后剩下问号就与问号匹配。看下面代码即可一目了然。
AC代码:
//
// Created by jal on 2019-05-22.
//#include <bits/stdc++.h>
using namespace std;
int main(){int n;cin >> n;map<char, list<int> >mp1, mp2;vector<pair<int, int> >v;string s1,s2;cin >> s1 >> s2;for(int i = 0; i < n; i++){mp1[s1[i]].push_back(i+1);mp2[s2[i]].push_back(i+1);}for(int i = 'a'; i <= 'z'; i++){while(mp1[i].size() > 0 && mp2[i].size() > 0){v.push_back({mp1[i].front(), mp2[i].front()});mp1[i].pop_front();mp2[i].pop_front();}while(mp1[i].size() > 0 && mp2['?'].size() > 0){v.push_back({mp1[i].front(), mp2['?'].front()});mp1[i].pop_front();mp2['?'].pop_front();}while(mp1['?'].size() > 0 && mp2[i].size() > 0){v.push_back({mp1['?'].front(), mp2[i].front()});mp1['?'].pop_front();mp2[i].pop_front();}}while(mp1['?'].size() > 0 && mp2['?'].size() > 0){v.push_back({mp1['?'].front(), mp2['?'].front()});mp1['?'].pop_front();mp2['?'].pop_front();}cout << v.size() << endl;for(auto i : v){cout << i.first << " " << i.second << endl;}
}
E. Superhero Battle
题目大意:
使h降到0以下,依次通过数组v的每一位,都要进行h+v[i],v[i]有正有负。这个数组持续循环下去。
解题思路:
先求数组v的前缀和sum数组,sum[n-1]就是v数组的全部项的累加和。设MIN为sum数组的最小值。
- 如果sum[n-1]大于0且h+MIN大于0,则一定无解。因为此时h只会增加不会减少
- 如果h+MIN小于0,则经过整场数组的轮数cnt为0,否则为cnt=ceil(1.0∗(h+MIN)/(−sum[n−1]))cnt=ceil(1.0*(h+MIN) / (-sum[n-1]))cnt=ceil(1.0∗(h+MIN)/(−sum[n−1])).剩下的h=h+sum[n−1]∗cnth =h+ sum[n-1]*cnth=h+sum[n−1]∗cnt,前面的cnt轮走过的步数为cnt∗ncnt * ncnt∗n。剩下的步数一定可以在一轮数组遍历中使得h降到0以下,所以遍历sum数组,找到h+sum[i]<=0h + sum[i] <= 0h+sum[i]<=0即可。
AC代码:
//
// Created by jal on 2019-05-22.
//#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main(){// ifstream cin("input.txt");LL h;int n;cin >> h >> n;vector<LL>v(n);for(int i = 0; i < n; i++){cin >> v[i];}vector<LL>sum(n);partial_sum(v.begin(), v.end(), sum.begin());LL cnt = 0;LL MIN = v[0];for(int i = 1; i < n; i++){if(sum[i] < MIN){MIN = sum[i];}}if(sum[n-1] >= 0 && h + MIN > 0){cout << -1 << endl;return 0;}cnt = ceil(1.0*(h+MIN) / (-sum[n-1]));if((h+MIN) < 0)cnt = 0;h += sum[n-1]*cnt;cnt *= n;for(int i = 0; i < n; i++){if(h + sum[i] <= 0){cnt += i+1;cout << cnt << endl;break;}}
}
codeforces竞赛1141题解相关推荐
- codeforces竞赛1169题解
A. Circle Metro 题目大意: 两个人乘坐不同方向的环形地铁,求两人是否会在某一站点相遇. 解题思路: 模拟即可 AC代码: 版本一(下标模拟) #include<bits/stdc ...
- 北京化工大学2018年10月程序设计竞赛部分题解(A,C,E,H)
目录 北京化工大学2018年10月程序设计竞赛部分题解(A,C,E,H) 竞赛事件相关 竞赛链接 竞赛题目 总结 北京化工大学2018年10月程序设计竞赛部分题解(A,C,E,H) 竞赛事件相关 竞赛 ...
- 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛题解
第八届"图灵杯"NEUQ-ACM程序设计竞赛个人赛题解 先抱怨一下,这场比赛的题锅太多了,而且正赶上状态不好,Ac 1/12就离谱.. H 数羊 给定n,m(1≤n≤109,0≤m ...
- c语言1106回文数,Codeforces 1106 简要题解
A题 传送门 读错题还能过样例我给自己点个赞. 题意简述:给一个010101网格SSS,问满足Si,j=Si+1,j+1=Si+1,j−1=Si−1,j−1=Si−1,j+1S_{i,j}=S_{i+ ...
- Educational Codeforces Round 95题解
Educational Codeforces Round 95题解 题目链接 代码链接 A. Buying Torches 题目大意: 你手上现在有一个木棍.有以下两种交换方式: 1.用一个木棍交换x ...
- 浙江农林大学第二十二届程序设计竞赛部分题解
浙江农林大学第二十二届程序设计竞赛 目录 瓜瓜打游戏(EASY) 题目思路 题目代码 瓜瓜喜欢做 A + B 题目思路 题目代码 瓜瓜不想上电工课 题目思路 题目代码 瓜瓜的 01 串 题目思路 题目 ...
- 2019河北省大学生程序设计竞赛(部分题解)
2019河北省大学生程序设计竞赛 B.Icebound and Sequence B题题解 G.点我 签到题 H.天神的密码 签到题 #include <iostream> #includ ...
- 【Codeforces div3-498】题解
Codeforces div3-498题解 A. Adjacent Replacements 对于这道题目就比较简单了,如果该数N为奇数,那么经过变换之后不变,如果该数为偶数则变为N - 1 #inc ...
- 2017广东工业大学程序设计竞赛决赛 题解源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)...
心得: 这比赛真的是不要不要的,pending了一下午,也不知道对错,直接做过去就是了,也没有管太多! Problem A: 两只老虎 Description 来,我们先来放松下,听听儿歌,一起&qu ...
- Codeforces 1110 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 众所周知ldxoildxoildxoi这种菜鸡选手是不会写HHH题的,因此该篇博客只有AAA题至GGG题的题解,实在抱歉. A题 传送门 题 ...
最新文章
- python lowercase_python 的 string.casefold 和 string.lower 方法区别?
- 神策数据受邀参加“两区”建设签约仪式
- kafka依赖zookeeper原因解析及应用场景
- c++ ftp服务端_FTP客户端软件介绍及使用
- Spring 中使用redis缓存方法记录
- 有关文档碎片(document fragment)的用法
- 老实说,WPF对自由开发者与小微型团体来说就是个毒瘤!
- iOS开发拓展篇-XMPP简单介绍
- ❤️缓存集合(一级缓存、二级缓存、缓存原理以及自定义缓存—源码+图文分析,建议收藏) ❤️
- AI独角兽商汤科技的内部服务容器化历程
- 【NIPS 2017】基于深度强化学习的想象力增强智能体
- 《采购与供应链管理》读书笔记
- Java代码-List集合求交集、补集(差集)
- 推荐一款微信小程序《诗词万卷》
- Gif录制神器GifCam
- 计算机工作流程新图,工作流程责任分工.doc
- 喵懂区块链23期|9012年了,侧链还是一只又死又活的薛定谔猫?
- python爬取微博博主历史博文存入Excel
- java 加密word_Java 加密和解密PDF文档
- 再来30个!中国联通5G应用创新案例