[贪心专题]CF549G,CF351E,CF226D,CF1276C,CF1148E,CF798D

文章目录

  • T1:CF1276C Beautiful Rectangle
    • title
    • solution
    • code
  • T2:CF226D The table
    • title
    • solution
    • code
  • T3:CF549G Happy Line
    • title
    • solution
    • code
  • T4:CF798D Mike and distribution
    • title
    • solution
    • code
  • T5:CF351E Jeff and Permutation
    • title
    • solution
    • code
  • T6:CF1148E Earth Wind and Fire
    • title
    • solution
    • code

T1:CF1276C Beautiful Rectangle

title

solution

在这里插入图片描述保证不重复,我们就按对角线这样填下去就可以了,这个很好想到
但注意行,列的变换不要这么写,因为可能是特殊的正方形

r = ( r + 1 ) % row;
c = ( c + 1 ) % col;

接下来返回考虑怎样确定这个矩阵的大小row,colrow,colrow,col,要求row<=colrow<=colrow<=col
我们可以暴力枚举rowrowrow
也就是说每一个数的最多出现次数要求一定小于等于rowrowrow,不然肯定有一行会有重复数字
然后我们把这些数字出现次数加起来,就能计算出列
注意在判断矩阵大小的时候必须row∗colrow*colrowcol来判断,不能单纯按统计的数字最多出现次数
因为不一定能整除rowrowrow,所以有些数不一定达到了上限的

code

#include <cmath>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define MAXN 400005
vector < pair < int, int > > g;
vector < vector < int > > ans;
vector < int > num;
int n, row, col;
int a[MAXN], b[MAXN], cnt[MAXN];int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%d", &a[i] ), b[i] = a[i];sort( a + 1, a + n + 1 );int m = unique( a + 1, a + n + 1 ) - a - 1;for( int i = 1;i <= n;i ++ ) b[i] = lower_bound( a + 1, a + m + 1, b[i] ) - a;for( int i = 1;i <= n;i ++ ) cnt[b[i]] ++;for( int i = 1;i <= m;i ++ ) g.push_back( make_pair( cnt[i], i ) );sort( g.begin(), g.end() );int now = 0;for( int i = 1;i <= sqrt( n );i ++ ) {int temp = 0;for( int j = 0;j < g.size();j ++ )temp += min( g[j].first, i );if( temp / i < i ) continue;else if( temp / i * i > now ) now = temp / i * i, row = i, col = temp / i;}printf( "%d\n%d %d\n", row * col, row, col );reverse( g.begin(), g.end() );for( int i = 0;i < g.size();i ++ ) {for( int j = 1;j <= min( g[i].first, row );j ++ )num.push_back( g[i].second );}ans.resize( row );for( int i = 0;i < row;i ++ ) ans[i].resize( col );int r = 0, c = 0;for( int i = 0;i < num.size();i ++ ) {ans[r][c] = num[i];r ++, c ++;if( r == row ) r = 0, c -= row - 1;if( c < 0 ) c += col;if ( c >= col ) c -= col;}for( int i = 0;i < row;i ++ ) {for( int j = 0;j < col;j ++ )printf( "%d ", a[ans[i][j]] );printf( "\n" );}return 0;
}

T2:CF226D The table

title

solution

本质就是个暴力
对于总和小于零的每一行,每一列都进行取反操作即可
当某一行或某一列操作次数为偶数的时候,其实相当于是无效操作,最后输出答案的时候判掉即可
为什么这么暴力就可以?——因为我们限制了操作的总次数极限就是1e61e61e6
把每一行和每一列的和加起来等于整个矩阵的总和的两倍,值域[−4e6,4e6][-4e6,4e6][4e6,4e6]
每次取反至少是−1=>1-1=>11=>1,整个矩阵总和的两倍至少增加444,当和无法再增加的时候就是每一行每一列都大于零

code

#include <cstdio>
#include <vector>
using namespace std;
#define MAXN 105
vector < int > r, c;
int n, m;
int row[MAXN], col[MAXN], visr[MAXN], visc[MAXN];
int a[MAXN][MAXN];int main() {scanf( "%d %d", &n, &m );for( int i = 1;i <= n;i ++ )for( int j = 1;j <= m;j ++ ) {scanf( "%d", &a[i][j] );row[i] += a[i][j];col[j] += a[i][j];}while( 1 ) {bool flag = 1;for( int i = 1;i <= n;i ++ )if( row[i] < 0 ) {visr[i] ++;row[i] = - row[i];for( int j = 1;j <= m;j ++ )col[j] -= ( a[i][j] << 1 ), a[i][j] = - a[i][j];flag = 0;break;}for( int i = 1;i <= m;i ++ ) if( col[i] < 0 ) {visc[i] ++;col[i] = - col[i];for( int j = 1;j <= n;j ++ )	row[j] -= ( a[j][i] << 1 ), a[j][i] = - a[j][i];flag = 0;break;}if( flag ) break;}for( int i = 1;i <= n;i ++ )if( visr[i] & 1 ) r.push_back( i );for( int i = 1;i <= m;i ++ )if( visc[i] & 1 ) c.push_back( i );printf( "%d", r.size() );for( int i = 0;i < r.size();i ++ )printf( " %d", r[i] );printf( "\n%d", c.size() );for( int i = 0;i < c.size();i ++ )printf( " %d", c[i] );return 0;
}

T3:CF549G Happy Line

title

solution

非常巧的一个点——对于第iii个数,不管它以后的位置在哪,它原来的下标iii值与valvalval的和是个定值
所以贪心就想到总和越大的越应该往后放
这样才有可能不减
如果有一个数iii的总和大于最后一个数的总和且在前面某个位置,那么数iii的值就等于总和减去现在的下标,本来值就比最后一个大,减去的又比最后一个小,自然就不可能成为不减序列

code

#include <cstdio>
#include <algorithm>
using namespace std;
#define MAXN 200005
struct node {int val, id;
}v[MAXN];
int n;bool cmp( node x, node y ) {return x.val + x.id < y.val + y.id;
}int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%d", &v[i].val ), v[i].id = i;sort( v + 1, v + n + 1, cmp );for( int i = 1;i <= n;i ++ )if( v[i].id + v[i].val == v[i - 1].id + v[i - 1].val )return ! printf( ":(" );else if( i > v[i].id + v[i].val ) return ! printf( ":(");for( int i = 1;i <= n;i ++ )printf( "%d ", v[i].id + v[i].val - i );return 0;
}

T4:CF798D Mike and distribution

title

solution

2∗∑i=1xa[p[i]]>∑j=1na[j],2∗∑i=1xb[p[i]]>∑j=1nb[j]2*\sum_{i=1}^xa[p[i]]>\sum_{j=1}^na[j],2*\sum_{i=1}^xb[p[i]]>\sum_{j=1}^nb[j]2i=1xa[p[i]]>j=1na[j],2i=1xb[p[i]]>j=1nb[j]
不管是aaa还是bbb数组,都减去一倍已选的数
其实最后的要求都转化为了,a,ba,ba,b数组已选的数的和要大于没选的数的和
⌊n2⌋+1\lfloor \frac{n}{2}\rfloor+12n+1这个特别要求入手
考虑分奇偶讨论
n=2kn=2kn=2k
aaa的从大到小排序,并两两分组
第一组的全选上,之后的每一组选择bbb较大的一个
接下来证明这个算法的正确性
我们每一组都选的bbb较大的一个,自然可以压制另一个的bbbbbb的要求已经达到
那么aaa怎么办呢?
如果较大的bbbaaa也较大,那自然更好,甭考虑
如果是较小的aaa,也不用害怕,因为我们第一组的两个aaa都选了
它们一定大于这一组里面较大的aaa,可以压制
那么后面遇到类似情况怎么办,最大的两个aaa已经用了,没关系
两个aaa用了,一定解救出前面较大的某些(个)aaa,拿来压制现在的aaa
就这么一个一个压制下去,最后让aaa也达到要求
奇数同理可得,不再重复

code

#include <cstdio>
#include <algorithm>
using namespace std;
#define MAXN 100005
struct node {int a, b, id;
}v[MAXN];
int n;bool cmp( node x, node y ) {return x.a > y.a;
}int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%d", &v[i].a ), v[i].id = i;for( int i = 1;i <= n;i ++ )scanf( "%d", &v[i].b );sort( v + 1, v + n + 1, cmp );printf( "%d\n", ( n >> 1 ) + 1 );if( n % 2 ) {printf( "%d ", v[1].id );for( int i = 2;i <= n;i += 2 )if( v[i].b > v[i + 1].b ) printf( "%d ", v[i].id );else printf( "%d ", v[i + 1].id );}else {printf( "%d %d ", v[1].id, v[2].id );for( int i = 3;i <= n;i += 2 )if( v[i].b > v[i + 1].b ) printf( "%d ", v[i].id );else printf( "%d ", v[i + 1].id );}return 0;
}

T5:CF351E Jeff and Permutation

title

solution

考虑数a,ba,ba,b,且∣a∣>∣b∣|a|>|b|a>b
aaa+++
如果bbbaaa前面,不管bbb±±±都不会有逆序对
如果bbbaaa后面,不管bbb±±±都会有逆序对
aaa−-
如果bbbaaa前面,不管bbb±±±都不会有逆序对
如果bbbaaa后面,不管bbb±±±都会有逆序对

我们发现,逆序对的产生只与两个数的相对位置以及较大数的正负有关

所以我们只需要考虑对于下标为iii的数,前面绝对值比他小的有多少个,后面比他小的有多少个,取个minminmin即可
至于比他大的数自然是交个比他大的数来管他们之间是否会有逆序对,不管这个数取正取负,逆序对都在较大数的决定上
所以彼此是相互独立的,不会造成影响

那么两个数的绝对值一样的时候呢?这个时候的正负不就有影响了吗?
所以我们该定义一个dp[i][j]:dp[i][j]:dp[i][j]:iii个数有jjj个为−-,然后进行转移
其实并不需要,可以证明绝对值一样的数一定会是前面一段全选负后面一段全是正
假设下标i<ji<ji<j∣a[i]∣=∣a[j]∣|a[i]|=|a[j]|a[i]=a[j]
如果iii选了正,意味着数列[1,i)[1,i)[1,i)个绝对值比iii小的个数多于(i,n](i,n](i,n]的个数
那么jjj而言,前面的数已经包含了[1,i)[1,i)[1,i),还多加了一段(i,j)(i,j)(i,j),那么前面绝对值小于它的数个数只会增加(不变)不会减小,后面(j,n](j,n](j,n]则只会减小(不变)不会增大
所以是不会彼此之间产生逆序对的,按照上面每个数独立判断的做法做即可

code

#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
#define MAXN 2005
int n, ans;
int p[MAXN];int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%d", &p[i] );for( int i = 1;i <= n;i ++ ) {int Left = 0, Right = 0;for( int j = 1;j < i;j ++ )if( fabs( p[i] ) <= fabs( p[j] ) ) continue;else Left ++;for( int j = i + 1;j <= n;j ++ )if( fabs( p[i] ) <= fabs( p[j] ) ) continue;else Right ++;ans += min( Left, Right );}printf( "%d", ans );return 0;
}

T6:CF1148E Earth Wind and Fire

title

solution

很常规的贪心思想,按值排序后,然后下标一一对应,即s[i]s[i]s[i]负责成为t[i]t[i]t[i]
然后我们从最大的开始往下判断,要知道sss一定先把多余的可以传递的传递给临近的
因为如果iii把多余的分给离他很远的s[j]s[j]s[j],则s[j]<=s[i+1]s[j]<=s[i+1]s[j]<=s[i+1]
就算加上了s[i]s[i]s[i]给的xxxs[j],s[i+1]s[j],s[i+1]s[j],s[i+1]之间的差距也不如将xxx分给s[i+1]s[i+1]s[i+1]
差距越大能传递的ddd越大
同时传递后要保证s[i]>=t[i]s[i]>=t[i]s[i]>=t[i],当循环到某一个数后,发现他的s<ts<ts<t,则无解
因为我们从大到小一一帮扶过来
此时的数一定接受了比他大的所有的数多出来的t[]−s[]t[]-s[]t[]s[]
全加上也没到要求
后面的数也帮不了它,因为s[该数]>=s[后面的数]s[该数]>=s[后面的数]s[]>=s[],无法进行转移

code

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define MAXN 300005
#define int long long
struct node {int val, id;
}s[MAXN], t[MAXN];
struct noded {int l, r, val;noded( int L, int R, int V ) {l = L, r = R, val = V;}
};
vector < noded > ans;
int n, sums, sumt;bool cmp( node x, node y ) {return x.val > y.val;
}signed main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ ) {scanf( "%d", &s[i].val );s[i].id = i, sums += s[i].val;}for( int i = 1;i <= n;i ++ ) {scanf( "%d", &t[i].val );t[i].id = i, sumt += t[i].val;}if( sums != sumt ) return ! printf( "NO" );sort( s + 1, s + n + 1, cmp );sort( t + 1, t + n + 1, cmp );int last = 1;for( int i = 1;i <= n;i ++ ) {if( s[i].val < t[i].val ) return ! printf( "NO" );while( s[i].val > t[i].val ) {while( t[last].val <= s[last].val ) last ++;int temp;temp = min( t[last].val - s[last].val, s[i].val - t[i].val );temp = min( temp, ( s[i].val - s[last].val ) >> 1 );s[i].val -= temp, s[last].val += temp;ans.push_back( noded( s[last].id, s[i].id, temp ) );}}printf( "YES\n%d\n", ans.size() );for( int i = 0;i < ans.size();i ++ )printf( "%lld %lld %lld\n", ans[i].l, ans[i].r, ans[i].val );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317887.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数位DP】CF 54C,509C,431D,628D,855E,1245F,95D

这一次有题解了&#xff01;&#xff01;T1&#xff1a;CF54C First Digit LawtitlesolutioncodeT2&#xff1a;CF509C Sums of DigitstitlesolutioncodeT3&#xff1a;CF431D Random TasktitlesolutioncodeT4&#xff1a;CF628D Magic NumberstitlesolutioncodeT5&#xff1a;…

C#如何安全、高效地玩转任何种类的内存之Memory(三)

前言我们都知道&#xff0c;.Net Core是微软推出的一个通用开发平台&#xff0c;它是跨平台和开源的&#xff0c;由一个.NET运行时、一组可重用的框架库、一组SDK工具和语言编译器组成&#xff0c;旨在让.Net developers可以更容易地编写高性能的服务应用程序和基于云的可伸缩服…

.netcore下的微服务、容器、运维、自动化发布

微服务1.1 基本概念1.1.1 什么是微服务&#xff1f;微服务架构是SOA思想某一种具体实现。是一种将单应用程序作为一套小型服务开发的方法&#xff0c;每种应用程序都在其自己的进程中运行&#xff0c;并采用轻量级的通讯机制&#xff08;TCP&#xff09;进行通信。这…

[选拔赛1]花园(矩阵快速幂),JM的月亮神树(最短路),保护出题人(斜率优化)

多年不考试&#xff0c;一夜回到解放前T1&#xff1a;花园titlesolutioncodeT2&#xff1a;月亮神树titlesolutioncodeT3&#xff1a;保护出题人titlesolutioncodeT1&#xff1a;花园 title 小 L 有一座环形花园&#xff0c;沿花园的顺时针方向&#xff0c;他把各个花圃编号为…

.NET的关于人脸识别引擎分享(C#)

最近在Github上找合适的人脸识别引擎&#xff0c;想要本地化用&#xff0c;不用开放的一些API&#xff08;比如腾讯AI、百度AI&#xff09;,有些场景联不了网&#xff0c;一开始搜索的是时候&#xff08;关键字&#xff1a;face recognition&#xff09;就找到了最出名的face_r…

UOJ#84-[UR #7]水题走四方【dp】

正题 题目链接:https://uoj.ac/problem/84 题目大意 有nnn个点的一棵树&#xff0c;111为根&#xff0c;两个人从根节点往下走&#xff08;只能从深度小的点走到深度大的点&#xff09;。 两个人每一秒都可以一条边&#xff08;也可以不移动&#xff09;&#xff0c;或者不消…

Docker最全教程——数据库容器化(十一)

终于按时完成第二篇。本来准备着手讲一些实践&#xff0c;但是数据库部分没有讲到&#xff0c;部分实践会存在一些问题&#xff0c;于是就有了此篇以及后续——数据库容器化。本篇将从SQL Server容器化实践开始&#xff0c;并逐步讲解其他数据库的容器化实践&#xff0c;中间再…

[选拔赛2 NOIP2018雅礼集训 Day3 u,v,w]玩个三角形(二维差分),玩个球(状压DP+map),玩个树(树上DP)

文章目录T1&#xff1a;玩个三角形titlesolutioncodeT2&#xff1a;玩个球titlesolutioncodeT3&#xff1a;玩个树titlesolutioncodeT1&#xff1a;玩个三角形 title 题目描述 考虑一个 n ∗ n 的矩阵 A&#xff0c;初始所有元素均为 0。 执行 q 次如下形式的操作&#xff…

2019 年起如何开始学习 ABP 框架系列文章-开篇有益

阅读文本大概需要 3.3 分钟。本系列文章推荐阅读地址为&#xff1a;52ABP 开发文档https://www.52abp.com/Wiki/52abp/latest/Welcome-to-52abp本文的目的是为了让刚刚接触 ABP 框架的同学或者准备接触 ABP 框架的同学&#xff0c;能够理解和搞明白 ABP 框架到底是怎么回事&…

【模板】差分约束算法

【模板】差分约束算法 题意&#xff1a; 题解&#xff1a; 模板题 算法讲解 给出一组包含 m 个不等式&#xff0c;有 n 个未知数。求任意一组满足这个不等式组的解&#xff0c;或判定无解。 连边之后跑最短路&#xff0c;保证每个连通块都没有负环即可。 也可以建源点s 0&a…

数论一之定理证明——裴蜀/威尔逊/费马/扩展欧几里得/[扩展]欧拉/[扩展]中国剩余定理,欧拉函数,逆元,剩余系,筛法

打死没想到会在H老师处学懂数论同余&#xff0c;整除模运算埃式筛法欧拉筛法最大公约数和最小公倍数辗转相除法更相减损术裴蜀定理威尔逊定理费马定理同余等价类、剩余系、缩系欧拉函数欧拉定理扩展欧拉定理区间逆元扩展欧几里得中国剩余定理扩展中国剩余定理利用以上所有知识进…

AT4437-[AGC028C]Min Cost Cycle【结论,堆】

正题 题目链接:https://www.luogu.com.cn/problem/AT4437 题目大意 有nnn个点的一张有向完全图&#xff0c;每个点有两个点权a,ba,ba,b。连接x,yx,yx,y两个点的边权为min{ax,by}min\{a_x,b_y\}min{ax​,by​}&#xff0c;求一条权值和最小的哈密顿回路。 1≤n≤105,1≤a,b≤1…

某银行大型管理系统端到端持续集成和交付实践

背景传统的银行IT系统研发流程从需求提出到产品交付往往具有较长的研发周期&#xff0c;纵观银行当下面临的市场环境&#xff0c;个人信贷消费升级&#xff0c;资管需求旺盛&#xff0c;普惠金融成为国家战略&#xff0c;来自银行同业和互联网金融的压力扑面而来&#xff0c;谁…

排列组合十一个性质公式及证明,错排数公式及证明

文章目录排列数组合数求组合数常用公式定义式递推式杨辉三角组合数常用性质及证明性质一性质二性质三性质四(二项式定理)性质五性质六性质七性质八性质九性质十性质十一错排数排列数 从nnn个物品中不放回地依次选mmm个物品&#xff0c;考虑顺序&#xff0c;有多少种方案&#…

引入用于 Azure IoT Edge 的 Visual Studio 工具

物联网开发人员&#xff1a;工具和经验引入用于 Azure IoT Edge 的 Visual Studio 工具今天&#xff0c;我们很高兴地发布用于 Visual Studio 2017 的 Azure IoT Edge 工具的预览版。Azure IoT Edge 是一个全托管服务&#xff0c;通过直接在跨平台物联网设备上部署并运行人工智…

P4878 [USACO05DEC]Layout G

P4878 [USACO05DEC]Layout G 题意&#xff1a; 题解&#xff1a; 这个题其实是差分约束的裸题&#xff0c;但是有几个坑要注意 1.题目说了&#xff0c;奶牛按照编号1…N排列&#xff0c;对于ML个输入&#xff0c;A< B ,所以关系是B - A < 10,而不是A - B <10,我一开…

【学习笔记】原根 / BSGS / 扩展BSGS证明及模板

文章目录原根BSGS大步小步算法扩展BSGS原根 如果两个整数a,ba,ba,b互质&#xff0c;则有aϕ(b)%b1a^{\phi(b)}\%b1aϕ(b)%b1 定义模bbb意义下的aaa的阶为使ad%b1a^d\%b1ad%b1的最小正整数ddd 显然&#xff0c;模bbb的阶d∣ϕ(b)d|\phi(b)d∣ϕ(b) 如果模bbb意义下aaa的阶为…

.Net Core分布式部署中的DataProtection密钥安全性

在.NetCore中默认使用DataProtection来保护数据&#xff0c;例如Cooike等。一般情况下DataProtection生成的密钥会被加密后存储&#xff0c;例如默认的文件存储可以看到使用了Windows DPAPI加密。但是如果更改默认设置例如使用的外部存储如redis则此时密钥默认是不加密的微软说…

scanf(“%s“)真的只开读入字符串大小就可以了吗??

文章目录前言还原过程计算机程序背后的故事总结瞎逼逼前言 艹艹艹艹艹艹&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;老子没想到没想到&#xff0c;靠&#xff01; 本人刚刚在做树链剖分“染色”一题的代码重构&#xff0c;上午打…

P5299-[PKUWC2018]Slay the Spire【dp】

前言 正题 题目链接:https://www.luogu.com.cn/problem/P5299 题目大意 有2n2n2n张牌&#xff0c; nnn张强化牌&#xff0c;每张上有一个正整数x(x>1)x(x>1)x(x>1)&#xff0c;如果使用后之后的每一张攻击牌伤害都会乘上xxx。nnn张攻击牌&#xff0c;每张上有一个正…