A. Ilya and a Colorful Walk:

题意: nnn个数,每个数都有一个属性,还有一个值。要求找到两个数,数字属性不同,求出最大的数字差值。
思路: 简单题,直接对所有数字排序,对于最大值找一个与其属性不同的最小值,再对于最小值,找一个与其属性不同的最大值,比较求出最大差值即可。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 3*1e5+100;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int mp[N][2],n;int main()
{memset(mp,-1,sizeof mp);scanf("%d",&n);rep(i,1,n) mp[i][0] = -1, mp[i][1] = 1e7;rep(i,1,n){int xx; scanf("%d",&xx);mp[xx][0] = max(mp[xx][0],i);mp[xx][1] = min(mp[xx][1],i);}int maxn = -1, pos, ans = -1, minn = 1e7;rep(i,1,n){if(mp[i][0] > maxn){maxn = mp[i][0];pos = i;}}rep(i,1,n){if(i != pos && mp[i][0] != -1) ans = max(ans,maxn-mp[i][1]);}rep(i,1,n){if(mp[i][1] < minn){minn = mp[i][1];pos = i;}}rep(i,1,n){if(i != pos && mp[i][1] != 1e7) ans = max(ans,mp[i][0]-minn);}printf("%d\n",ans);return 0;
}

B. Alyona and a Narrow Fridge

题意: 一个高度为hhh的冰箱,冰箱内一共两列。现在有nnn个物品,需要往冰箱中进行插板,使得前kkk个物品能放入冰箱,求kkk的最大值。(1≤n≤103)(1\leq n \leq 10^3)(1≤n≤103)
思路: 由于nnn比较小,直接枚举k即可,然后将前kkk个物品排序,倒序放入冰箱,判断是否可以成功即可完成此题。当然也可以将枚举改为二分,也可以通过此题。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 1000+100;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int n,h,a[N];int solve(int x)
{int tmp[N], th = h;rep(i,1,x) tmp[i] = a[i];sort(tmp+1,tmp+1+x);int i = x, j = max(i-1,1), ans = 0;while(i >= 1 && th > 0){if(th < tmp[i]) break;else if(max(tmp[i],tmp[j]) <= th){ans += 1;if(i != j) ans++;th -= max(tmp[j],tmp[i]);i = j-1, j = max(i-1,1);}else if(a[j] <= h){ans += 1;break;}}if(ans != x) return 0;else return 1;
}int main()
{scanf("%d%d",&n,&h);rep(i,1,n) scanf("%d",&a[i]);int ans = 0;// sort(a+1,a+1+n);rep(i,1,n){if(solve(i)) ans = i;else break;}  printf("%d\n",ans);return 0;
}

C. Ramesses and Corner Inversion

题意: 给你两个矩形A、B,矩形中每个位置可能为111或000,现在可以在矩形AAA中选取一个子矩形,然后翻转这个子矩形的四个端点。问能否通过这种方式将A翻转成B。
思路: 可以发现,翻转一个子矩阵的四个角,不会改变矩阵AAA与矩阵BBB中每行每列不相同区域个数的奇偶性,即只需要判断矩阵AAA与矩阵BBB中每行每列中不相同区域个数是否为偶数即可完成此题。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 500+10;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int n,m,a[N][N],b[N][N],row[N],col[N];int main()
{scanf("%d%d",&n,&m);rep(i,1,n)rep(j,1,m) scanf("%d",&a[i][j]);rep(i,1,n)rep(j,1,m){scanf("%d",&b[i][j]);if(a[i][j] != b[i][j]) row[i]++, col[j]++;}int jud = 0;rep(i,1,n)  if(row[i]%2 != 0) jud = 1;rep(i,1,m)if(col[i]%2 != 0) jud = 1;if(jud) printf("No\n");else printf("Yes\n");return 0;
}

D. Frets On Fire

题意: 一共nnn个序列,已知每个序列开头元素的大小,序列为等差数列,公差为111,序列长度为1018+1。先有qqq组询问,每组询问给出lll与rrr,求出这nnn个序列在[l,r][l,r][l,r]这个区间内一共有多少个不相同的数。(1≤n≤105,1≤q≤105)(1\leq n \leq 10^5, 1\leq q \leq 10^5)(1≤n≤105,1≤q≤105)
思路: 其实这个问题可以抽象为现在有nnn个区间,这nnn个区间长度均为r−l+1r-l+1r−l+1,已知每个区间开头元素,问nnn个区间重叠之后一共有多少个不一样的数字。
很明显,我们首先需要对每个区间开头元素进行排序,然后来考虑相邻两个区间会有多少重复的元素。假如区间111与区间222差距为lenlenlen,如果 r−l+1≤lenr-l+1\leq lenr−l+1≤len,则区间111与区间222没有相互覆盖,而如果 len<r−l+1len < r-l+1len<r−l+1,则区间111的有效长度为lenlenlen,因此我们求出相邻两个区间的差距,存入数组 d[x]d[x]d[x],然后对于 ddd 数组进行排序,然后二分出第一个间距大于等于 r−l+1r-l+1r−l+1的点,该点之后的区间有效长度均为r−l+1r-l+1r−l+1,而该点之前的区间有效长度均为lenlenlen。
此处还需要注意,由于差分数组只维护了前n−1n-1n−1个区间,即最后一个区间的贡献显然是r−l+1r-l+1r−l+1,因此最后的答案还需要加上最后一个区间的长度。到此,即可完成此题。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 1e5+100;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int n,m;
ll a[N],d[N],sum[N];int main()
{scanf("%d",&n);rep(i,1,n) scanf("%lld",&a[i]);sort(a+1,a+1+n);d[1] = sum[0] = 0;rep(i,2,n) d[i] = a[i]-a[i-1];sort(d+2,d+1+n);rep(i,1,n) sum[i] = sum[i-1]+d[i];scanf("%d",&m);rep(i,1,m){ll xx,yy; scanf("%lld%lld",&xx,&yy);int l = 2, r = n, ans = -1;while(l <= r){int mid = (l+r)>>1;if(d[mid] >= (yy-xx+1)){ans = mid; //第一个大于等于k的点r = mid-1;}else l = mid+1;}// LOG3("xx",xx,"yy",yy,"ans",ans);ll total = 0;if(ans == -1)total = sum[n]-sum[0]+(yy-xx+1);elsetotal = (n-ans+2)*(yy-xx+1)+sum[ans-1]-sum[0];printf("%lld ",total);}printf("\n");return 0;
}

E. Pavel and Triangles

题意: 一共有nnn类木棒,每类木棒都有其固定的数目,现在需要用这些木棒组成三角形。组成三角形的规则是,同类型的三根木棒,或者同类型的两根木棒+一根比这个类型编号更小的木棒,问最多可以组成多少根木棒。
思路: 很明显,这是一个贪心题目,但是怎么贪是一个问题。比赛时,怎么贪心都过不去,还是太欠缺贪心的练习,哭…
我们现在来研究一下这题应该如何去做,当你匹配到jjj时,这时你有三种选择。① 选择<j,j,jj,j,jj,j,j> ②选择<k1,j,jk_1,j,jk1​,j,j>,k1k_1k1​类型更小 ③ 选择<j,k2,k2j,k_2,k_2j,k2​,k2​>,k2k_2k2​类型更大。可以发现必定是优先进行第二种选择的匹配,因为你已经匹配到了jjj,k1k_1k1​已经无法进行匹配了,而此时也只用消耗两个jjj,而第一种选择需要消耗三个jjj,显然没有第二种优。而第三种选择,可以发现第三种选择最多和第二种一致,绝对不会比第二种更优,因此我们优先考虑第二种选择。
然后匹配完所有k1k_1k1​之后,我们只剩下了两种选择,然后我们来考虑一下哪种方案更优。假设我们现在一共有333个jjj,222个a1a_1a1​、a2a_2a2​、a3a_3a3​。第一种选择<j,j,jj,j,jj,j,j>,<a1,a2,a2a_1,a_2,a_2a1​,a2​,a2​>,<a1,a3,a3a_1,a_3,a_3a1​,a3​,a3​> 形成333个三角形。第三种选择<j,a1,a1j,a_1,a_1j,a1​,a1​>、<j,a2,a2j,a_2,a_2j,a2​,a2​>、<j,a3,a3j,a_3,a_3j,a3​,a3​>,也是形成333个三角形。而现在是我们假设还有222个a1a_1a1​、a2a_2a2​、a3a_3a3​,如果没有,则第三种选择很可能会变差。因此第三种选择不会优于第一种选择,所以我们直接进行第一种选择即可。
所以最后的算法是,先匹配222个的,再匹配333个的。
总结: 贪心问题总是在当前做出看来是最好的选择,而不从整体最优上加以考虑,做出的选择是局部最优解。贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。而在这道贪心问题中,如果优先考虑当前元素对后续元素的贡献,则违背了只考虑当前最优的原则,这也是我比赛时犯的错误,需要深刻反思。
贪心问题的证明可以从局部策略着手,证明其他的几种策略中没有比我所执行的这个策略更优的,充分列举其他情况,即可完成证明。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 3*1e5+100;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int n;
ll ans,a[N];int main()
{scanf("%d",&n);rep(i,1,n) scanf("%lld",&a[i]);ll sum = 0;rep(i,1,n){ll xx = min(a[i]/2,sum); ans += xx;sum -= xx;a[i] -= xx*2;ans += a[i]/3;a[i] = a[i]%3;sum += a[i];}printf("%lld\n",ans);return 0;
}

【Codeforces Global Round 2】A-E题解 【Frets On Fire、Pavel and Triangles】相关推荐

  1. Codeforces Global Round 24 A~D 题解

    说明 题目链接 就做出AB题,C题想了一个半小时.和我同场竞技的两位选手都做出了C,还是我太菜了555~ A - Doremy's Paint 答案等价于求包含不同元素个数最大的区间,就是全区间. # ...

  2. Codeforces Global Round 1

    Codeforces Global Round 1 题解:The Editorial of the First Codeforces Global Round A:其实mod 2计算一下就行了 B:删 ...

  3. Codeforces Global Round 1 晕阙记

    Codeforces Global Round 1 晕阙记 我做这场比赛的时候晕得要死.做这三道题做太久了,rating涨不起来啊! A 如果愿意的话你可以看做是膜2意义下的运算,写快速幂等各种膜运算 ...

  4. Codeforces Global Round 3

    Codeforces Global Round 3 A. Another One Bites The Dust 有若干个a,有若干个b,有若干个ab.你现在要把这些串拼成一个串,使得任意两个相邻的位置 ...

  5. Codeforces Global Round 14 F. Phoenix and Earthquake 思维 + 并查集

    传送门 文章目录 题意: 思路: 题意: 给你nnn个点,mmm条边,限制xxx,每个点都有沥青aia_iai​,定义合并两个点即两点之间有边且au+av≥xa_u+a_v\ge xau​+av​≥x ...

  6. 【Codeforces Global Round 23】B. Rebellion

    Codeforces Global Round 23中B. Rebellion Codeforces比赛记录 文章目录 题目链接: 一.B. Rebellion 题目意思: 上思路: 总结 B. Re ...

  7. Codeforces Global Round 4-D. Prime Graph(伯特兰-切比雪夫定理)

    题目:Codeforces Global Round 4-D. Prime Graph 题意:给出n(顶点的个数),要求所得图满足: 1.无平行边和自环 2.边的总数是个质数 3.每个点的度(也就是点 ...

  8. codeforces global round 23

    constest :codeforces global round 23 contest time:2022.10.16 contest grade: 2800 contest rating chan ...

  9. Codeforces Global Round 2 D. Frets On Fire (动态开点线段树,沙雕写法)

    题目链接:D. Frets On Fire 思路:明明可以离散化+二分写,思路硬是歪到了线段树上,自闭了,真实弟弟,怪不得其他人过得那么快 只和查询的区间长度有关系,排完序如果相邻的两个点的差值小于等 ...

  10. Codeforces Global Round 2(CF1119)

    这场题目设置有点问题啊,难度:Div.2 A->Div.2 B->Div.2 D->Div.2 C->Div.2 D->Div.1 D-> Div.1 E-> ...

最新文章

  1. [计划]二〇〇七年年度计划
  2. tensorflow 使用
  3. Stanford UFLDL教程 逻辑回归的向量化实现样例
  4. Qt Creator在外部应用程序上运行Valgrind工具
  5. 当你扛不住的时候就读读
  6. 朴素贝叶斯原理及实现
  7. python tkinter选择路径控件_如何使用tkinter在Python中选择目录并存储位置
  8. 847方波放大电路_分析运放7大经典电路,有图有真相,详解每个电路原理!
  9. EOSIO:EOSIO最新版1.4.0创建测试账户
  10. python查找路径代码_Python搜索路径
  11. php和mysql防伪网站源码,2015年最新php+mysql防伪查询程序源码微信认证查询含7套模板...
  12. 使用ARCGIS对shp数据添加投影坐标系
  13. 《普林斯顿微积分读本》 第一章:函数、图像和直线
  14. 根据url链接来下载资源
  15. vue插件大全汇总,你要的都这里,赶紧收藏下!
  16. 大唐杯5G题库大全(1)
  17. minecraft pythonapl_Minecraft API
  18. 基于JAVA实现的图形化页面置换算法
  19. java lazy_在Java8中模拟Lazy
  20. iQOONeo6SE和红米k40区别 哪个好 iQOONeo6SE和红米k40哪个值得买 两者配置对比

热门文章

  1. 2012年中国系统架构师大会 即将开幕
  2. CISCO路由器的备份与还原(2)
  3. Layer 7 过滤 (官网介绍)
  4. [导入]一个Form验证的方案
  5. 计算机外围设备哪两类,计算机原理2010年4月真题(02384)
  6. 南阳oj-----懒省事的小明(set)
  7. linux openssh升级8.1,ssh服务升级8.1
  8. python 无限循环小程序设计_Python如何实现小程序 无限求和平均
  9. 【CF1369D】TediousLee(找规律递推——计数)
  10. 【UVA1599】Ideal Path理想路径--两种约束条件(!!双向bfs+非简单图的最短路+无向图邻接记录法)