Codeforces Round #579 (Div. 3) 套题 题解
A. Circle of Students
题目:https://codeforces.com/contest/1203/problem/A
题意:一堆人坐成一个环,问能否按逆时针或者顺时针正好是 1-n的顺序
思路:水题,把数组开两倍,或者标记当前位置都可以
#include<bits/stdc++.h>
#define maxn 100005
#define mod 1000000007
using namespace std;
typedef long long ll;
int a[maxn],n;
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
int dex=;
for(int i=;i<=n;i++){
if(a[i]==){
dex=i;
break;
}
}
int flag=;
int k=dex;
int z=,num=;
while(num<n){
k++;
if(k==n+) k=;
if(a[k]!=z+) break;
num++;
z++;
}
if(num==n) flag=;
//printf("num=%d k=%d z=%d\n",num,k,z);
k=dex;
z=,num=;
while(num<n){
k--;
if(k==) k=n;
if(a[k]!=z+) break;
num++;
z++;
}
if(num==n) flag=;
if(flag) printf("YES\n");
else printf("NO\n");
}
}
B. Equal Rectangles
题目:https://codeforces.com/contest/1203/problem/B
题意:有4*n根木棍,现在问能否组成n个面积相等的矩形
思路:首先我们组成第一个矩形肯定是最小和最大,然后第二个是次小和次大.....所以我们对木棒排序,然后两个指针判是否可行即可
#include<bits/stdc++.h>
#define maxn 100005
#define mod 1000000007
using namespace std;
typedef long long ll;
int a[maxn],n;
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
n=*n;
for(int i=;i<=n;i++) scanf("%d",&a[i]);
sort(a+,a+n+);
int l=,r=n,z=a[]*a[n];
int flag=;
while(l<r){
if(a[l]!=a[l+]||a[r]!=a[r-]){
flag=;
break;
}
if(a[l]*a[r]!=z){
flag=;
break;
}
z=a[l]*a[r];
l+=;
r-=;
}
if(flag) printf("NO\n");
else printf("YES\n");
}
}
C. Common Divisors
题目:https://codeforces.com/contest/1203/problem/C
题意:有一个序列,现在求一个数x,这个x是序列所有数的约数,求这样的x的数量
思路:我们首先能求出最大公约数,然后其他约数必然是最大公约数的因子,所以我们求出最大公约数的因子数即可
#include<bits/stdc++.h>
#define maxn 400005
#define mod 1000000007
using namespace std;
typedef long long ll;
ll a[maxn],n;
int main(){
scanf("%I64d",&n);
for(ll i=;i<=n;i++){
scanf("%I64d",&a[i]);
}
if(n==){
ll sum=;
ll g=a[];
for(ll i=;i*i<=g;i++){
if(g%i==){
sum++;
if(i!=g/i) sum++;
}
}
cout<<sum;
return ;
}
ll g=__gcd(a[],a[]);
for(ll i=;i<=n;i++){
g=__gcd(g,a[i]);
}
ll sum=;
for(ll i=;i*i<=g;i++){
if(g%i==){
sum++;
if(i!=g/i) sum++;
}
}
cout<<sum;
return ;
}
D1+D2. Remove the Substring
题目:https://codeforces.com/contest/1203/problem/D2
题意:有两个串,你可以执行一次删除操作,删除一段连续的字符,删除完之后第二个串依然是第一个串的子序列,求最大的可以删除的字符数
思路: 这个其实我们枚举删除的一段字符是在第二个串的哪两个字符中间即可,特别的判断下一个整的序列的左边右边,当然一个串里面可能出现多次字符出现位置,因为我们要求最大所以我们直接求一个前缀,所有字符出现的第一次位置,一个后缀,所有字符出现的最后一次,这样就能保证中间差距尽量大,然后我们枚举删除的字符在哪两个之间求max即可
#include<bits/stdc++.h>
#define maxn 200005
#define mod 1000000007
using namespace std;
typedef long long ll;
char s1[maxn],s2[maxn];
ll b1[maxn],b2[maxn];
int main(){
cin>>s1>>s2;
ll len1=strlen(s1);
ll len2=strlen(s2);
for(int i=,j=;i<len1;i++){
if(s1[i]==s2[j]){
b1[j]=i;
j++;
if(j==len2) break;
}
}
for(int i=len1-,j=len2-;i>=;i--){
if(s1[i]==s2[j]){
b2[j]=i;
j--;
if(j==-) break;
}
}
ll mx=;
mx=max(mx,b1[]);
mx=max(mx,len1-b1[len2-]-); mx=max(mx,b2[]); mx=max(mx,len1-b2[len2-]-); for(int i=;i<len2-;i++){
mx=max(mx,b2[i+]-b1[i]-);
}
cout<<mx;
return ;
}
自己的假题意:我一开始理解的是删除后,第二个串是第一个串的子串,求最大的删除字符数
思路:和上面一样,要求一个前缀和后缀,不过我这个求得前缀和后缀有点区别,
举个栗子:abcdddeffggg 与 bcdfg
那么我就可以组成得的几种组合分别有
bcdfg+"" b+cdfg bc+dfg bcd+fg bcdf+g
分别记录上面的子串第一次出现的位置,和最后出现的一次位置,然后和上面一样求一个max,要记录这些暴力肯定不行,用n次kmp去找位置也不现实,但是其实我们可以只用一次kmp就可以求出来,因为这些子串本身就是前缀的连续关系
可以拿我这个假题意出个题,代码在此奉上
#include<bits/stdc++.h>
#define maxn 200005
#define mod 1000000007
using namespace std;
typedef long long ll;
char s1[maxn],s2[maxn];
ll nxt[maxn],len1,len2;
ll b1[maxn],b2[maxn];
void getnext(){
ll i=,j=-;
nxt[]=-;
while(i<len2){
if(j==-||s1[i]==s2[j]){
nxt[++i]=++j;
}
else j=nxt[j];
}
}
void kmp(char s1[],char s2[],ll b[]){
ll i=,j=;
getnext();
while(i<len1){
if(j==-||s1[i]==s2[j]){
i++;j++;
if(b[j]==-){
b[j]=i;
}
if(j==len2){
j=;
}
}
else j=nxt[j];
}
}
int main(){
cin>>s1>>s2;
len1=strlen(s1);
len2=strlen(s2);
if(len1<=len2){
cout<<"";
return ;
}
for(int i=;i<maxn;i++){
b1[i]=-;
b2[i]=-;
}
kmp(s1,s2,b1);
for(int i=;i<len1/;i++){
char t=s1[i];
s1[i]=s1[len1-i-];
s1[len1-i-]=t;
}
for(int i=;i<len2/;i++){
char t=s2[i];
s2[i]=s2[len2-i-];
s2[len2-i-]=t;
}
kmp(s1,s2,b2);
for(int i=;i<=len2;i++){
if(b1[i]!=-)
b1[i]--;
}
for(int i=;i<=len2/;i++){
ll t=b2[i];
b2[i]=b2[len2-i+];
b2[len2-i+]=t;
}
for(int i=;i<=len2;i++){
if(b2[i]!=-)
b2[i]=len1-b2[i];
}
ll mx=;
if(b1[len2]!=-){
mx=max(b1[len2]-len2+,len1-b1[len2]-);
}
//cout<<mx<<"\n";
if(b2[]!=-){
mx=max(mx,max(b2[],len1-b2[]-len2));
}
//cout<<mx<<"\n";
for(int i=;i<len2;i++){
if(b1[i]!=-&&b2[i+]!=-){
mx=max(mx,b2[i+]-b1[i]-);
}
}
/*for(int i=1;i<=len2;i++){
cout<<b1[i]<<" ";
}
cout<<"\n";
for(int i=1;i<=len2;i++){
cout<<b2[i]<<" ";
}
cout<<"\n";*/
cout<<mx;
return ;
}
/*
abcddbbbzle
cdz
*/
E. Boxers
题目:https://codeforces.com/contest/1203/problem/E
题意:每个数可以变成自己和-1 +1的三种数,除了1,他不能变成比1更小的数,然后给你一组数,问你可以变成几个不同的数
思路:水题,直接从小到大排序,然后能尽量小就尽量小,打打标记即可
#include<bits/stdc++.h>
#define maxn 400005
#define mod 1000000007
using namespace std;
typedef long long ll;
ll a[maxn],n;
ll vis[maxn];
int main(){
cin>>n;
for(int i=;i<=n;i++) cin>>a[i];
sort(a+,a+n+);
ll sum=;
for(int i=;i<=n;i++){ if(vis[a[i]-]==&&a[i]!=){
vis[a[i]-]=;
sum++;
}
else if(vis[a[i]]==){
vis[a[i]]=;
sum++;
}
else if(vis[a[i]+]==){
vis[a[i]+]=;
sum++;
}
}
cout<<sum;
return ;
}
F1. Complete the Projects (easy version)
题目:https://codeforces.com/contest/1203/problem/F1
题意:有n个项目,每个项目有个最低要求资格,还有一个价值,会加到自身价值身上,最开始自己有一个价值,然后问是否能做完所有项目,做项目顺序可以自己排
思路:对于价值为正的项目,很明显我们可以直接从小到大的把项目做掉,这样一定是最优的,对于负数来说,我们排差值,差值大的,说明损耗对于自身的损耗较小,这样才能保证自己还有能力做大项目,又能保证做完一个大项目后因为扣的太多而不能去做小项目
#include<bits/stdc++.h>
#define maxn 200005
#define mod 1000000007
using namespace std;
typedef long long ll;
ll n,m;
struct sss
{
ll x,y;
}a[maxn],b[maxn];
ll num1,num2;
int cmp1(struct sss x,struct sss y){
return x.x<y.x;
}
int cmp2(struct sss x,struct sss y){
if(x.x+x.y==y.x+y.y) return x.x>y.x;
return x.x+x.y>y.x+y.y;
}
int main(){
cin>>n>>m;
ll x,y;
for(int i=;i<n;i++){
cin>>x>>y;
if(y>=){
a[num1].x=x;
a[num1++].y=y;
}
else{
b[num2].x=x;
b[num2].y=y;
num2++;
}
}
sort(a,a+num1,cmp1);
sort(b,b+num2,cmp2);
int flag=;
for(int i=;i<num1;i++){
if(m>=a[i].x) m+=a[i].y;
else{
flag=;
break;
}
}
if(flag) printf("NO");
else{
for(int i=;i<num2;i++){
if(m>=b[i].x) m+=b[i].y;
else{
flag=;
break;
}
}
if(!flag&&m>=) printf("YES");
else printf("NO");
}
return ;
}
F2. Complete the Projects (hard version)
题目:https://codeforces.com/contest/1203/problem/F2
题意:和F1一样,但是这个是问能做的最多项目数是多少
思路:对于F1来说直接按差值排,是为了完成所有项目,所以顺序大的小的在前无所谓,但是这个有可能不能完成,但是可以换个方向多完成几个,对于这种情况较多复杂度又要求高的我们就会想到用dp
我们直接对于每个项目来说的话,考虑当前项目取或者不取,但是我们又需要其他价值的最优值,所以其实我们就可以转化成一个01背包,dp[i][j]代表前i件里面j价值能取得最多项目数是多少
#include<bits/stdc++.h>
#define maxn 100005
#define mod 1000000007
using namespace std;
typedef long long ll;
struct sss{
ll x,y;
}a[maxn],b[maxn];
ll n,m,num1=,num2=;
ll dp[][];
int cmp1(struct sss x,struct sss y){
return x.x<y.x;
}
int cmp2(struct sss x,struct sss y){
return x.x+x.y>y.x+y.y;
}
int main(){
scanf("%lld%lld",&n,&m);
for(int i=;i<n;i++){
ll x,y;
scanf("%lld%lld",&x,&y);
if(y>=){
a[num1].x=x;
a[num1++].y=y;
}
else{
b[num2].x=x;
b[num2++].y=y;
}
}
sort(a+,a+num1,cmp1);
sort(b+,b+num2,cmp2);
ll ans=;
for(int i=;i<num1;i++){
if(m>=a[i].x){
ans++;
m+=a[i].y;
}
else break;
}
memset(dp,,sizeof(dp));
for(int i=;i<num2;i++){
for(int j=m;j>=;j--){
if(j+b[i].y>=&&j>=b[i].x) dp[i][j+b[i].y]=max(dp[i-][j+b[i].y],dp[i-][j]+);
else dp[i][j]=max(dp[i][j],dp[i-][j]);
}
}
ll mx=;
for(int i=;i<=m;i++){
mx=max(mx,dp[num2-][i]);
}
cout<<ans+mx;
}
Codeforces Round #579 (Div. 3) 套题 题解的更多相关文章
- Codeforces Round #612 (Div. 2) 前四题题解
这场比赛的出题人挺有意思,全部magic成了青色. 还有题目中的图片特别有趣. 晚上没打,开virtual contest打的,就会前三道,我太菜了. 最后看着题解补了第四道. 比赛传送门 A. An ...
- Codeforces Round #741 (Div. 2)部分题题解
我果然还是太菜了,就写了两道题....真是水死了.... A The Miracle and the Sleeper 简化题意:给定\(l,r\),求\(a\)%\(b\)的最大值,其中\(r> ...
- Codeforces Round #361 (Div. 2) 套题
A - Mike and Cellphone 问有没有多解,每个点按照给出的序列用向量法跑一遍 #include<cstdio> #include<cstring> #incl ...
- Codeforces Round #369 (Div. 2) 套题
A:模拟水题不说 #include <iostream> #include <string.h> #include <algorithm> #include < ...
- Codeforces Round #367 (Div. 2) 套题
吐槽:只能说是上分好场,可惜没打,唉 A:Beru-taxi (水题,取最小值) #include <cstdio> #include <cstring> #include & ...
- Codeforces Round #744 (Div. 3) G题题解
淦,最后一道题没写出来,...还是我太菜了,不过这个题确实比较有趣. G. Minimal Coverage 简化题意:就是你处在坐标轴的0点上,给你一个序列\(a_i\),每次你可以选择向左走\(a ...
- Codeforces Round #573 (Div. 2) D题题解
一.题目 Tokitsukaze, CSL and Stone Game Tokitsukaze和CSL正在玩一些石头游戏. 一开始,有n堆的石头,第i堆石头数记为 \(a_i\),两人轮 ...
- Codeforces Round #579 (Div. 3)
Codeforces Round #579 (Div. 3) 传送门 A. Circle of Students 这题我是直接把正序.逆序的两种放在数组里面直接判断. Code #include &l ...
- Codeforces Round #378 (Div. 2) D题(data structure)解题报告
题目地址 先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA).做到C题时看到题目情况非常 ...
随机推荐
- is_selected()检查是否选中该元素
is_selected()检查是否选中该元素,一般针对单选框,复选框,返回的结果是bool 值, 以百度登录页面为案例,来验证"下次自动登录"是否勾选,默认是勾选的,返回的结 果应 ...
- 前端 CSS 盒子模型 目录
CSS盒子模型介绍 padding border属性
- spring扩展点之PropertyPlaceholderConfigurer
原理机制讲解 https://leokongwq.github.io/2016/12/28/spring-PropertyPlaceholderConfigurer.html 使用时多个配置讲解 ht ...
- mock.js的运用
一:概念 Mock.js是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试.提供了以下模拟功能: 根据数据模板生成模拟数据 模拟 Ajax 请求,生成并返回模拟数据 基于 H ...
- KMP字符串匹配 模板 洛谷 P3375
KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.(如果 ...
- Kinect V2入门之数据获取步骤
在Kinect for windows SDK2.0中,获取并处理数据源接口步骤如下: Sensor -> Source -> Reader -> Frame -> Data ...
- 类———用类定义对象———error:C++表达式必须包含类类型
//原文参考https://blog.csdn.net/lanchunhui/article/details/52503332 你以为你定义了一个类的对象,其实在编译器看来你是声明了一个函数 clas ...
- laravel5.5结合bootstrap上传插件fileinput 上传图片
引入相关js <script src="{{ asset('bootstrap-fileinput/js/fileinput.js') }}"></script& ...
- Spring KafkaTemplate 注解式实现 工厂模式
实现注解式注入kafkaTemplate 生产者和消费者,简化配置文件 目录 消费者工厂 /** * 消费者工厂 */ @EnableKafka @Configuration public class ...
- Scrapy 教程(三)-网站解析
有经验的人都知道,解析网站需要尝试,看看得到的数据是不是想要的,那么在scrapy中怎么尝试呢? 调试工具-shell 主要用于编写解析器 命令行进入shell scrapy shell url 这个 ...