A - Romaji CodeForces - 1008A
B - Turn the Rectangles CodeForces - 1008B
C - Reorder the Array CodeForces - 1008C
D - Saving Snuuk AtCoder - 4190
E - + Graph AtCoder - 4191 (留坑,至今未果,寻病终

  • A
  • B
  • C
  • D

A

题目简述
把一个数组分成连续的k段,每一段的价值为这一段最大元素的值,求每一段价值之和的最大值。并输出每一段的长度。
分析
贪心地思考一下,这个数组无论如何都可以分成k段(n>=k)则将这个数组前k大的数字分在k个部分中 问题就在于怎么输出 细节考虑比较多 考试的时候实现得不是很好 也卡了很久

//考试的实现
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 2005
int N,K,ans,cn;
struct node{int v,p;
}a[MAXN],c[MAXN];
int b[MAXN];
bool cmp(node x,node y)
{return x.v>y.v;
}
bool cmp2(node x,node y)
{return x.p<y.p;
}
int main()
{scanf("%d %d",&N,&K);for(int i=1;i<=N;i++){scanf("%d",&a[i].v);a[i].p=i;b[i]=a[i].v;}sort(a+1,a+N+1,cmp);for(int i=1;i<=K;i++){ans+=a[i].v;c[++cn].v=a[i].v;c[cn].p=a[i].p;}sort(c+1,c+cn+1,cmp2);int n=1;printf("%d\n",ans);int last=0;for(int i=1;i<=N;i++)if(b[i]==c[n].v){if(n==cn){printf("%d",N-last);return 0;}printf("%d ",i-last);last=i;n++;}
}

就是保存了前k大的数在数组中的位置,输出的时候以此分节,但却是实现不够优秀(包括最后的for循环其实多余了 都已经存有了位置 for 1~k 就OK)。

//更优秀的实现
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 2000;
struct node{int val, id;
}a[MAXN + 5];
bool operator < (node a, node b) {return a.val < b.val;
}
int b[MAXN + 5], bcnt;
int main() {int n, k;scanf("%d%d", &n, &k);for(int i=1;i<=n;i++) {scanf("%d", &a[i].val);a[i].id = i;}`sort(a+1, a+n+1);int ans = 0;for(int i=n;i>=n-k+1;i--) {ans += a[i].val;b[++bcnt] = a[i].id;}b[++bcnt] = n+1;printf("%d\n", ans);sort(b+1, b+bcnt+1);printf("%d", b[2]-1);for(int i=2;i<bcnt;i++)printf(" %d", b[i+1]-b[i]);
}

B

题目简述
把数组分成连续的3段 使第一段的元素之和等于第三段的元素之和 每一段都可以为空 求第一段元素之和的最大值
分析
Tip:正解&简洁的代码请往下翻
我一拿到就想到了前缀和&后缀和
a[i]表示1~i的和 b[j]表示j~N的和 若i,j满足i < j并且a[i]==b[j] 更新ans
然后 我就这么写了 然后 T了QAQ

#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 200006
int N,ans=-10;
int a[MAXN],b[MAXN],c[MAXN];
int main()
{scanf("%d",&N);for(int i=1;i<=N;i++){scanf("%d",&a[i]);b[i]=b[i-1]+a[i];}for(int i=N;i>=1;i--)c[i]=c[i+1]+a[i];for(int i=1;i<N;i++)for(int j=i+1;j<=N;j++)if(b[i]==c[j])ans=max(ans,b[i]);if(ans==-10) ans=0;printf("%d\n",ans);
}

然后后来。。。搞了一个挺麻烦的操作。。。把前缀和后缀数组搞成了一个 标记了一下属性
然后就是 记得一定要开long long 10^9加起来就爆了 QAQ
如果是黑箱测试 我这场考试就凉凉了

//考场实现
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 200005
int N,ans;
int a[MAXN];
struct node{long long v;int p,t;
}b[2*MAXN];
bool cmp(node x,node y)
{return x.v>y.v;
}
int main()
{scanf("%d",&N);for(int i=1;i<=N;i++){scanf("%d",&a[i]);b[i].v=b[i-1].v+a[i];b[i].p=i;b[i].t=1;}for(int i=N;i>=1;i--)b[i+N].v=b[i+N+1].v+a[i],b[i+N].p=i,b[i+N].t=2;sort(b+1,b+2*N+2,cmp);for(int i=1;i<=2*N;i++)if(b[i].v==b[i+1].v&&((b[i].p<b[i+1].p&&b[i].t==1&&b[i+1].t==2)||(b[i].p>b[i+1].p&&b[i].t==2&&b[i+1].t==1))){printf("%lld\n",b[i].v);return 0;}printf("0\n");return 0;
}
//long long不开毁前程

然后这个差不多的思想 有一个特别简单的实现 (赛后shared)

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,t;
long long a[200001],ans;
int main() {scanf("%d",&n);for(int i=1; i<=n; i++)scanf("%I64d",&a[i]),a[i]+=a[i-1];for(int i=1; i<=n; i++) {t=lower_bound(a+1,a+1+n,a[n]-a[i])-a;if(a[t]==a[n]-a[i]&&i<=t)ans=a[i];}printf("%lld",ans);return 0;
}

赛后看了这个实现 我。。。QAQ
最关键的就是在第二个for循环里面
根本不需要另外用一个后缀数组 a[n]-a[i]==b[i] 然后low_bound()求出第一个大于等于这个数的位置(对于这道题而言,upper _bound也可以)
如果在前缀里面 能够找到与之相等的数 并且后缀的位置大于前缀 则合法 更新ans

这道题还有一个思路就是用滑动窗口的思想 设置左右边界 由于sum具有单调性(所有的元素都是正数),则可以通过调整边界来调整sum的关系

#include<iostream>
#include<cstdio>
#include<cstring>
#include<climits>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
#define MAXN 200000
int n,d[MAXN+5],l,r;
long long sum1,sum2,ans;
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&d[i]);int l=0,r=n+1;while(l<r){if(sum1==sum2)ans=max(ans,sum1),l++,r--,sum1+=d[l],sum2+=d[r];if(sum1<sum2)l++,sum1+=d[l];if(sum1>sum2)r--,sum2+=d[r];}printf("%lld",ans);
}

C

题目简述
2个长度为n的字符串 可以进行如下交换
1.a[i]与a[n-i+1]
2.a[i]与b[i]
3.b[i]与b[n-i+1]
可以将两个字符串 改变其中的字符 问至少要改变多少个字符才能使这2个字符串完全相等

分析
有点模拟的意味 但不是纯暴力 进行分类讨论即可
注意a[i]与b[j]和b[i]与a[j]直接交换是非法的 需进行2次交换 交换后顺序与直接交换不同

然后 坑点来了
敲黑板
题目上说只能修改a的字符
如果 if(a[i]==a[j]) swap(a[i],b[i]),swap(a[i],a[j]);
这个操作就会把a[j]和b[i]换了
当后面访问到a[j]时如果你发现无法与b[j]匹配,后面的程序就会修改a[j]的值
但实际上题目要求是先修改值,再交换位置
所以修改a[j]就相当于修改b[j],就违反了规则

#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 100005
char a[MAXN],b[MAXN];
int N,ans;
int main()
{scanf("%d",&N);scanf("%s\n%s",a+1,b+1);for(int i=1;i<=N;i++)if(a[i]!=b[i]){int j=N-i+1;if(j>i){if(a[i]==b[j]) swap(b[i],b[j]);else if(b[i]==a[j]) swap(a[i],a[j]);//else if(a[i]==a[j]) swap(a[i],b[i]),swap(a[i],a[j]);else if(a[j]==b[j]) swap(a[i],a[j]),swap(b[i],b[j]);else if(b[i]==b[j]) swap(a[i],b[i]),swap(b[i],b[j]);else ans++;}else ans++;}printf("%d\n",ans);
}

还有一种做法,就是满足这样的一种性质:可以互相交换的4个地方的字符一定4个一样或者有2种字符,每种2个。
其实也比较好做,但是我没做

D

题意简述

Kenkoooo去旅行,有n个城市,m条火车线路。每条线路有两种权值:日元和Snuke,任选一种即可。开始时,他有10 ^15日元,在任意一个城市,他都可以将日元换成Snuke,但必须全部换完,且只能换一次,并且城市i会在i年后不能兑换货币。他每年都会去旅行,对于每一年求最大能够省下的Snuke。

思路分析

很朴素的一个想法当然就是枚举在哪个车站换钱,但是肯定会超时。
怎么办呢?我们折中一下,因为不管在哪个车站换,在那个车站以前,用的是日元,在那个车站以后,用的是Snuke。
所以我们分别以起点和终点为起点,这话怎么这么绕,分别以日元和Snuke为边权,找最短路,然后枚举断点。

但是这道题的有(恶)趣(心)之处呢,就在于它有很多很多年,每一年的可供换钱的车站还有变化。年数要是太大,时间也不好受。

于是我们可以这样进行一个优化。
每一年会关掉i号窗口,如果我们把时间轴倒着看,就是每一年会多开第i号窗口。而对于第i年来说,由于变化的只是第i号窗口有没有开,所以对于上一年(实际是下一年,这里把时间轴倒着看的)求出的那个ans值,表示的是在i+1~n号窗口换的最优值,那我们只需将上一年的ans值,与这一年在第i号窗口换钱的值进行比较,取最小即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define MAXN 100005
#define LL long long
#define INF 1e18
int N,M,S,T,u,v;
LL a,b,f=1e15,ans[MAXN];
LL Min(LL x,LL y)
{if(x>y) return y;return x;
}
struct graph{int cnt,head[MAXN],vis[MAXN];LL dis[MAXN];struct Edge{int next,to;LL dis;}edge[2*MAXN];queue<int> q;void addedge(int from,int to,LL dis){edge[++cnt].next=head[from];edge[cnt].to=to;edge[cnt].dis=dis;head[from]=cnt;}void spfa(int s){for(int i=1;i<=N;i++)dis[i]=INF;memset(vis,0,sizeof(vis));q.push(s); vis[s]=1; dis[s]=0;while(!q.empty()){int x=q.front(); q.pop();vis[x]=0;for(int i=head[x];i;i=edge[i].next){int to=edge[i].to;if(dis[to]>dis[x]+edge[i].dis){dis[to]=dis[x]+edge[i].dis;if(!vis[to]) q.push(to),vis[to]=1;}}}}
}g1,g2;
int main()
{scanf("%d %d %d %d",&N,&M,&S,&T);for(int i=1;i<=M;i++){scanf("%d %d %lld %lld",&u,&v,&a,&b);g1.addedge(u,v,a); g1.addedge(v,u,a);g2.addedge(v,u,b); g2.addedge(u,v,b);}g1.spfa(S); g2.spfa(T);ans[N+1]=INF;for(int i=N;i>=1;i--) ans[i]=Min(ans[i+1],g1.dis[i]+g2.dis[i]);for(int i=1;i<=N;i++)printf("%lld\n",f-ans[i]);return 0;
}

P.S:终于知道了咋在结构体里面搞函数,跟在外面其实是一样的写法。

20180716 [AtCoder]CF697 EASY+SoundHound HARD【值得琢磨实现细节】相关推荐

  1. 最长非单调增序列(最长非单调增序列,,要用N*LOG N(非常值得琢磨的算法。)...

    http://acm.pku.edu.cn/JudgeOnline/problem?id=1887 (最长非单调增序列,,要用N*LOG N(不然会超时.)) 二分模板: int Find(int a ...

  2. 世界人口钟实时数据_中美面积人口数据对比,2020年8月,值得了解的细节

    一.面积 中国陆地面积约960万平方公里,内海和边海的水域面积约为470多万平方公里,大致是2:1的关系. 美国,百度百科的面积是937万平方公里,传统教科书上比我国面积略小,排名世界第四.按照美国自 ...

  3. url 里面 等号_【Python成长之路】从零学爬虫给微信公众号阅读量作个弊:刷阅读量...

    [写在前面] 小燕同学:鹏哥,我在微信公众号上写的一些美妆博客,都没什么阅读量,老板要求我在这个月底至少让几篇博客阅读量达到10W+,你说我要不要每天自己去刷或者找水军呀? 鹏哥:博客刷阅读量?这不是 ...

  4. 实验吧 writeup

    实验吧 WP 有几个题没做完,正在不断更新中,欢迎提问,如果 markdown 格式有错误也请呼我 WEB 认真一点! 没做出来~~~~~~~~~~~~~~~~~ 过滤了union sleep and ...

  5. [ME]不知道第几次学c语言,仍觉得水深莫测

    首先声明这篇东西是个人的碎碎念,没有任何干货. 接下c语言课助教的活儿时还没什么感觉,快要开学了,才感觉到紧张,逼着自己开始看老师发来的课件,说是查错,其实算是自己再好好学一遍,免得到时候面对同学们的 ...

  6. 吃亏是福--创业[3]

    宋朝时,李士衡在馆阁任职,一次出使高丽,一名武将担任副使.高丽方面赠送了礼品财物,李士衡并不在意,只是把它交给副使管理.当时船底出现隙缝漏水,副使把李士衡得到的丝绸细绢垫放在船底,然后放上自己的东西以 ...

  7. 三十而立,立的是什么?(r11笔记第70天)

    三十而立,来源于<论语.为政>"吾十有五,而志于学.三十而立.四十而不惑.五十而知天命.六十而耳顺,七十而从心所欲,不逾矩".按照孔子之前的意思,三十而立,不是表面的成 ...

  8. 关于数据存储的那些事1

    数据,异父异母的亲兄弟? Part1:数据类型 内置 自定义 构造 意义 内存空间 视角 C语言数据类型大致可以分为两类,内置类型:char,int,long,long long,float,doub ...

  9. 如何理解社交效应「蒸发式降温」?

    咖友提问:如何理解"社交效应-蒸发式降温"? 经常有人问起新浪微博是如何一步一步衰退的,同时也就有人给出"社交效应-蒸发式降温"这样的回答.请问,究竟该如何理解 ...

最新文章

  1. vue 怎么全局到入常量_vue定义全局变量和全局方法的方法示例
  2. PHP多种序列化/反序列化的方法 json_encode json_decode
  3. python画一颗心_利用python画一颗心的方法示例
  4. Qt设置QWidget背景色4种方法
  5. 牛书终于在卓越网上架
  6. 反射根据每一列的列名获取List T 中的列值
  7. kite:Python 代码自动补全神器
  8. JSLint报错翻译
  9. Mac Python IDLE中如何更改字体
  10. 炒股50问——走向职业操盘的简单问答!
  11. DDCTFMulTzor-xoortol的使用
  12. Android Performance之工具篇(1)-systrace
  13. 实战Nagios网络监控(2)—— Nagios+Nrpe监控其他主机
  14. 奇迹暖暖登录显示服务器满,奇迹暖暖登录不是全屏
  15. Eclipse Android Junit Test 测试实例
  16. 第7课用计算机写作文优质课例,有趣的电脑课作文9篇
  17. python爬虫一:爬虫简介
  18. 计算机科学论文写作5-写硕士论文
  19. Google瓦片地图URL
  20. top 与 margin-top的区别

热门文章

  1. 【word】空白页空白行删除不了,按delete
  2. Flutter MD5加密工具类
  3. iview中纯CSS美化select和Cascader滚动条
  4. java生成dat文件怎么打开_可以使用哪个软件工具打开Java程序生成的dat数据文件?...
  5. Samba服务---SMB协议
  6. 三菱PLC分拣程序基于三菱FX系列的分拣程序,可用于学习
  7. 西门子SMART200和三菱D700变频器485通讯例程
  8. 电路串联和并联图解_什么是串联,什么是并联…求图解
  9. 腾讯云COS创建Bucket报错
  10. (二十)unity shader之——————基于物理的渲染技术(PBS):下篇(PBS技术拓展:全局光照、伽马校正、HDR)