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题时看到题目情况非常 ...
随机推荐
- Slience is the sleep that nourishes wisdom
cumulative: 积聚的 lag. v. 落后 backfire. n. 事与愿违 segregated. adj. 分隔的 back-and-forth: 来回地 initiative. ad ...
- win10安装Tensorflow1.9GPU版本
前言 看到DateWhale出了一篇安装教程(微信公众号DateWhale),决定体验一下Tensorflow1.9的GPU版本..其实一开始装的是2.0,但是tf.Session()就报错了,说是2 ...
- 使用extract-text-webpack-plugin插件后报错
如果你使用的webpack是4+版本,那么尝试运行npm install extract-text-webpack-plugin@next ,即可解决问题 然而最好的解决办法是在webpack4+的版 ...
- arm初识
一.CPU从指令集角度分类 1.1. CISC (X86) 1.1. 1. CISC CPU 指complex instruction set computer复杂指令集CPU 1.1.2. CIS ...
- 06-REST Framework - API
# Django REST Framework# 1. REST- 前后端分离- API-ApplicationProgrammingInterface - 为了应付千变万化的前端需求- REST:R ...
- 在Python中使用protobuf2.6.1 string format utf-8 and unicode error
版本信息: protobuf: v2.6.1 python: 2.7 关于在Python中使用protobuf时 string格式字段的编码问题 在python中编码格式多采用utf-8格式.而pro ...
- Vue准备
Vue 模板 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UT ...
- 【玩转Eclipse】——eclipse实现代码块折叠-类似于VS中的#region……#endregion
[玩转Eclipse]——eclipse实现代码块折叠-类似于VS中的#region……#endregion http://www.cnblogs.com/Micheal-G/articles/507 ...
- Jmeter--函数助手之随机函数_Random(随机函数)
各函数调用方法如下:1)__Random( , , ),获取值的方式:${__Random( param1,param2 ,param3 )},param1为随机数的下限,param2为随机数的上限, ...
- Manacher || Luogu P3805【模板】manacher算法
题面:[模板]manacher算法 代码: #include<cstdio> #include<cstring> #include<iostream> #defin ...