文章目录

  • 前缀和与差分数组
    • [HNOI2003]激光炸弹
      • 前缀和解法(他又不变,,,前缀和就能搞定吧?)
        • 这种地方出现的错误(部分数据过不去)可能是少个等于之类的边界问题
        • 2021-3-10复习,这里非常聪明的从1开始,到5001(输入也+1),整个求和矩阵向右下方移一位,把a[0][x] a[x][0] 都设为0,这样访问a[i-1][j]的时候就都是0,不用特判
      • 线段树+扫描线解法
    • Tallest Cow-----差分数组
      • 这个应该是线段树了吧,不对,应该也不用?差分数组就行吧
      • 差分数组就行,两个之间的-1,也就是【a+1】 -- 【b】++
      • 但我没想明白a<=b的条件怎么用就过了?
      • 可能一个序列给两遍,要去重
      • 标记数组有点大了,下次可以试试用map
    • 2021.3.10复习:///cows[0]=H 这里体现基数,之前cows数组代表身高差,另外cows[p]一定为0
    • IncDec Sequence
      • 我们最终的目标是将差分数组变成第一个位置是最终的数字,2~n都是0
      • 每次对[l,r]进行+1/-1,相当于在差分后的数组上对l进行+1/-1,然后对r+1进行-1/+1
      • 特殊的,如果r=n,那么就相当于对l进行了+1/-1!!!!!!!!!2021.3.10
      • 那么我们统计差分后的数组的2~n号位置上每个位置上的数
      • 令pos为所有正数的和,neg为所有负数的和的绝对值
      • 那么首先是pos和neg对消 可能会剩下
      • ~~剩下的有两种选择:自己消掉或者与1号位置对消~~
      • 看做求出原序列的差分之后,将 S[2...n] 全部变为0所需的最少的步数和可以使 S[1] 变为多少种不同的数。
      • 故第一问答案为max(pos,neg) 第二问答案为abs(pos-neg)+1
        • 注意点:1.最好还是建两个数组,一个存原来的,一个存差分,不然容易出错
        • 2.另外这道狗题要用longlong(淦欧)
      • 2021.3.10 所剩余的数有两种选择!!!!!!
        • 另外 b[2]到b[n]都变成0就可以了
      • 2021.4.17总结:
    • Best Cow Fences
      • 二分+类前缀和(这道题真的离谱到家了)
        • 另外这个题好像动规还是贪心里面那个一串数从左往右最大值!!!(check里面就是这个思路)
        • 二分枚举平均值,验证当前的平均值是不是区间最大
          • “先二分答案。接着对于每个候选答案,尽量在O(n)时间内验证。”
      • [C++ 中的 inline 用法](https://www.runoob.com/w3cnote/cpp-inline-usage.html)
    • Cinema(离散化)
      • 离散化
        • 离散化的解法:
      • 排序
      • 我看一大堆离谱题解,这稀疏的用个map不就得了嘛
        • malloc动态开数组时需要赋初值(也可以用memset很快的),另外还发现了上面的问题(最后一组的M

前缀和与差分数组

原理与性质
https://www.cnblogs.com/mrpeng2333/p/11183654.html


[HNOI2003]激光炸弹

链接:https://ac.nowcoder.com/acm/problem/20032 来源:牛客网

一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标。
现在地图上有n(N ≤ 10000)个目标,用整数Xi,Yi(其值在[0,5000])表示目标在地图上的位置,每个目标都有一个价值。
激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆破范围,即那个边长为R的正方形的边必须和x,y轴平行。
若目标位于爆破正方形的边上,该目标将不会被摧毁。
输入描述:
输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示 xi,yi ,vi 。
输出描述:
输出文件仅有一个正整数,表示一颗炸弹最多能炸掉地图上总价值为多少的目标(结果不会超过32767)。
示例1
输入
复制
2 1
0 0 1
1 1 1
输出
复制
1


前缀和解法(他又不变,,,前缀和就能搞定吧?)

先录入价值,然后a[i][j]表示以(1,1)为左上角,(i,j)为右下角所构成的矩阵的价值和(二维前缀和矩阵)
这样b[i+m][j+m]-b[i+m][j]-b[i][j+m]+b[i][j]直接减就求出R内的值(其实就是暴力)
https://blog.csdn.net/weixin_44382711/article/details/112742528

这种地方出现的错误(部分数据过不去)可能是少个等于之类的边界问题

2021-3-10复习,这里非常聪明的从1开始,到5001(输入也+1),整个求和矩阵向右下方移一位,把a[0][x] a[x][0] 都设为0,这样访问a[i-1][j]的时候就都是0,不用特判

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
int a[maxn][maxn]={0};
int main()
{int n,R;cin>>n>>R;int xi,yi,vi;for(int i=0;i<n;i++){cin>>xi>>yi>>vi;a[xi+1][yi+1]=vi;}for(int i=1;i<=5000;i++){for(int j=1;j<=5000;j++)///遍历每一个点,计算以(1,1)为左上角,(i,j)为右下角的价值和{a[i][j]=a[i][j-1]+a[i-1][j]-a[i-1][j-1]+a[i][j];}}int ans=0;for(int i=0;i<=5000-R;i++)///这里要写等与号///而且不能改成1!!!!!!{for(int j=0;j<=5000-R;j++){ans=max(ans,a[i+R][j+R]-a[i+R][j]-a[i][j+R]+a[i][j]);///反过来的话:ans=max,,,,,,  a[i][j]-a[i][j-R]-a[i-R][j]+a[i-R][j-R];}}cout<<ans;return 0;
}

线段树+扫描线解法

https://blog.csdn.net/weixin_44382711/article/details/112738169
https://blog.csdn.net/icefox_zhx/article/details/78077506


Tallest Cow-----差分数组

链接:https://ac.nowcoder.com/acm/problem/25044 来源:牛客网

FJ's N (1 ≤ N ≤ 10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the height H (1 ≤ H ≤ 1,000,000) of the tallest cow along with the index I of that cow.
FJ has made a list of R (0 ≤ R ≤ 10,000) lines of the form "cow 17 sees cow 34". This means that cow 34 is at least as tall as cow 17, and that every cow between 17 and 34 has a height that is strictly smaller than that of cow 17.
For each cow from 1..N, determine its maximum possible height, such that all of the information given is still correct. It is guaranteed that it is possible to satisfy all the constraints.
----------------------------------------------------------------------------------------------
N(1≤N≤10000)头1..N奶牛排成一行。每头牛都有一个正整数的高度(这有点秘密)。
你只知道最高奶牛的身高H(1≤H≤1000000)以及该奶牛的位置I。
FJ列出了R(0≤R≤10000)行,形式为“17牛见34牛”。
这意味着34号奶牛至少和17号奶牛一样高,17到34号之间的每头奶牛的身高都比17号奶牛要小。
对于从1..N开始的每头母牛,确定其最大可能高度,以便给出的所有信息仍然正确。可以保证满足所有的约束条件。
输入描述:
Line 1: Four space-separated integers: N, I, H and R
Lines 2..R+1: Two distinct space-separated integers A and B (1 ≤ A, B ≤ N), indicating that cow A can see cow B.
输出描述:
Lines 1..N: Line i contains the maximum possible height of cow i.
示例1
输入
复制
9 3 5 5
1 3
5 3
4 3
3 7
9 8
输出
复制
5
4
5
3
4
4
5
5
5


这个应该是线段树了吧,不对,应该也不用?差分数组就行吧

差分数组就行,两个之间的-1,也就是【a+1】 – 【b】++

但我没想明白a<=b的条件怎么用就过了?

可能一个序列给两遍,要去重

标记数组有点大了,下次可以试试用map

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
int cows[maxn]={0};
///这个憨批题可能一道条件出两遍
bool judge[maxn][maxn];///默认0
int main()
{int N,I,H,R;cin>>N>>I>>H>>R;cows[0]=H;///每个代表与前面的牛的身高高多少,可以负数///不用管N cows[I],他肯定不会处在两端点之间,最后他的和肯定为0;int a,b;while(R--){cin>>a>>b;if(a>b)swap(a,b);if(judge[a][b]==true)continue;cows[a+1]--;cows[b]++;judge[a][b]=true;}for(int i=1;i<=N;i++){cows[i]+=cows[i-1];///cows[0]=H 这里体现基数,之前cows数组代表身高差,另外cows[p]一定为0}for(int i=1;i<=N;i++){cout<<cows[i]<<endl;}return 0;
}

2021.3.10复习:///cows[0]=H 这里体现基数,之前cows数组代表身高差,另外cows[p]一定为0

///每个代表与前面的牛的身高高多少,可以负数
///不用管N cows[I],他肯定不会处在两端点之间,最后他的和肯定为0;
注意一个序列给两遍,要去重的情况!!!!!!!!!!!


IncDec Sequence

链接:https://ac.nowcoder.com/acm/problem/50929
来源:牛客网

给定一个长度为 n(n \leq 10^5 )(n≤10
5) 的数列{a_1,a_2,…,a_n}a
1
​   ,a
2
​   ,…,a
n
​   ,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一。
求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
输入描述:
第一行一个正整数n。
接下来n行,每行一个整数,第i+1行的整数表示a_ia
i
​   。
输出描述:
第一行输出最少操作次数。
第二行输出最终能得到多少种结果。
示例1
输入
复制
4
1
1
2
2
输出
复制
1
2
备注:
对于100%的数据,n=100000,0 \leq ai \lt 21474836480≤ai<2147483648

https://www.cnblogs.com/719666a/p/10089194.html
https://www.luogu.com.cn/blog/TheShadow/p4552-poetize6-incdec-sequence-you-qu-di-ci-fen-ti-xie

我们最终的目标是将差分数组变成第一个位置是最终的数字,2~n都是0

每次对[l,r]进行+1/-1,相当于在差分后的数组上对l进行+1/-1,然后对r+1进行-1/+1

特殊的,如果r=n,那么就相当于对l进行了+1/-1!!!!!!!!!2021.3.10

那么我们统计差分后的数组的2~n号位置上每个位置上的数

令pos为所有正数的和,neg为所有负数的和的绝对值

那么首先是pos和neg对消 可能会剩下

剩下的有两种选择:自己消掉或者与1号位置对消

看做求出原序列的差分之后,将 S[2…n] 全部变为0所需的最少的步数和可以使 S[1] 变为多少种不同的数。

故第一问答案为max(pos,neg) 第二问答案为abs(pos-neg)+1

注意点:1.最好还是建两个数组,一个存原来的,一个存差分,不然容易出错

2.另外这道狗题要用longlong(淦欧)

2021.3.10 所剩余的数有两种选择!!!

比如是正数:则是这个数之后的数都比这个数之前的大(假设前后都是0)
与S[1]配对:使这个数之前的数增加,也就是s[1]+1 s[x]-1
与S[n+1]配对:使这个数之后的数减小(都减一),也就是s[n+1]+1 s[x]-1(s[n+1]应该是与最后一个数的差值,为负数)
负数的话就相反

另外 b[2]到b[n]都变成0就可以了

2021.4.17总结:

eg:
22225555
00003000
这样结果可以是全2,全3,全4,全5 (左边往上+或者右遍往下减)
也就是3+1种


Best Cow Fences

大意是说,给你一个正整数序列,找出一个区间使得平均值最大,要求该区间的长度大于等于F。

二分+类前缀和(这道题真的离谱到家了)

另外这个题好像动规还是贪心里面那个一串数从左往右最大值!!!(check里面就是这个思路)

二分枚举平均值,验证当前的平均值是不是区间最大

“先二分答案。接着对于每个候选答案,尽量在O(n)时间内验证。”


https://www.cnblogs.com/liucongyu/p/6357610.html
http://www.cppblog.com/varg-vikernes/archive/2010/03/02/108737.aspx
http://www.voidcn.com/article/p-dgfakbof-bxn.html
https://blog.csdn.net/qq_42500298/article/details/82915017(这个代码好)

C++ 中的 inline 用法

解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,
inline 只适合涵数体内代码简单的涵数使用,不能包含复杂的结构控制语句例如 while、switch,并且不能内联函数本身不能是直接递归函数(即,自己内部还调用自己的函数)。
它如果认为函数不复杂,能在调用点展开,就会真正内联,并不是说声明了内联就会内联,声明内联只是一个建议而已。

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 100005
int N,F;
double a[maxn],sum[maxn];
double rmaxsum[maxn];
double le,ri,mid;
bool checker(double val)
{//    for(int i=N;i>=1;i--)
//    {//        rmaxsum[i]=max(a[i]-val,rmaxsum[i+1]+a[i]-val);
//        /// 每个数都减val 看看右侧的选不选
//        ///定义rmaxsum[i]为以i为起点,向右延长的最大和。
//        ///如果rmax[i+1]>=0,那么rmax[i]=rmax[i+1]+a[i]。
//        ///若rmax[i+1]<0,那么不如扔掉i+1及其之后的数字,故此时rmax[i]=a[i]。
// /// !!! 左侧的最大和肯定比右侧可能性大(包含),所以从右向左(递推)
//    }double sum1=sum[F-1]-(F-1)*val;for(int i=F;i<=N;i++)///从左往右看,求所有可能的区间{double sum2=sum[i]-sum[i-F]-F*val;sum1=sum1+a[i]-val;///向右生长的要还是不要a[i]sum1=max(sum1,sum2);///是直接往右查F个大,还是接着之前的那个已经查了一部分的大if(sum1>-1e-5){///i+F-1到i-1的和///去掉当前验证的平均值的和(F长)大于0///说明这个数列存在平均在比这个还大的return true;}}return false;}int main()
{cin>>N>>F;le=maxn;ri=0;///牛的数量肯定大于等于0for(int i=1;i<=N;i++){cin>>a[i];sum[i]=sum[i-1]+a[i];///b[i]是和,两个之间的一减就出来ri=max(ri,a[i]);le=min(le,a[i]);}double eps=1e-5;///误差while(le<ri-eps)///标准二分{mid=(ri+le)/2;if(checker(mid)){le=mid;}else{ri=mid;}}cout<<int(ri*1000)<<endl;return 0;
}

Cinema(离散化)

链接:https://ac.nowcoder.com/acm/problem/50936
来源:牛客网

大意:
有 n 个人,每人会且仅会一种语言.  (n ≤ 2e5)
语言有各自的编号(≤ 1e9)
这些人去看电影,一共有 m 种电影. (m ≤ 2e5)
每个电影的声音与字幕语言都不一样.
若有人的语言与声音语言一样,则称这个人很高兴♂.
若有人的语言与字幕语言一样,则称这个人比较高兴.
现让你选择一场电影,使得此电影中,很高兴的人最多,在此条件下,再使比较高兴的人最多.Moscow is hosting a major international conference, which is attended by nscientists from different countries. Each of the scientists knows exactly one language. For convenience, we enumerate all languages of the world with integers from 1 to 10^910
9.
In the evening after the conference, all n scientists decided to go to the cinema. There are m movies in the cinema they came to. Each of the movies is characterized by two distinct numbers — the index of audio language and the index of subtitles language. The scientist, who came to the movie, will be very pleased if he knows the audio language of the movie, will be almost satisfied if he knows the language of subtitles and will be not satisfied if he does not know neither one nor the other (note that the audio language and the subtitles language for each movie are always different).
Scientists decided to go together to the same movie. You have to help them choose the movie, such that the number of very pleased scientists is maximum possible. If there are several such movies, select among them one that will maximize the number of almost satisfied scientists.输入描述:
The first line of the input contains a positive integer n (1 \leq n \leq 200 000)(1 ≤n≤200 000) — the number of scientists.
The second line contains n positive integers a_1,a_2, \dots ,a_na
1
​   ,a
2
​   , …,a
n
​   (1 ≤a_i ≤ 10^9)(1 ≤a
i
​   ≤ 10
9), where aiis the index of a language, which the i-th scientist knows.
The third line contains a positive integer m(1\leq m\leq 200 000)(1≤m≤ 200 000)— the number of movies in the cinema.
The fourth line contains m positive integers b_1,b_2,\dots,b_mb
1
​   ,b
2
​   ,…,b
m
​   (1 ≤b_j ≤ 10^9)(1 ≤b
j
​   ≤ 10
9), where bjis the index of the audio language of the j-th movie.
The fifth line contains m positive integers c_1,c_2, \dots,c_mc
1
​   ,c
2
​   , …,c
m
​   (1 ≤c_j ≤ 10^9)(1 ≤c
j
​   ≤ 10
9), where cj is the index of subtitles language of the j-th movie.
It is guaranteed that audio languages and subtitles language are different for each movie, that is b_j \not= c_jb
j
​   
​   =c
j
​   .
输出描述:
Print the single integer — the index of a movie to which scientists should go. After viewing this movie the number of very pleased scientists should be maximum possible. If in the cinema there are several such movies, you need to choose among them one, after viewing which there will be the maximum possible number of almost satisfied scientists.
If there are several possible answers print any of them.
示例1
输入
复制
3
2 3 2
2
3 2
2 3
输出
复制
2
示例2
输入
复制
6
6 3 1 1 3 7
5
1 2 3 4 5
2 3 4 5 1
输出
复制
1

离散化

离散化
https://blog.csdn.net/s_999999/article/details/99080549
离散化:两种离散化方式详解
https://blog.csdn.net/weixin_43061009/article/details/82083983

离散化的解法:

https://blog.csdn.net/weixin_45719073/article/details/104267772
用abc三个数组来存编号,然后用d来去重,d里面存着所有的index,d对应着num 这样查一个就可以在d里面查index(语言编号)对应的i(该语言对应的数组编号),然后上num++ – 查询人数,另外再给d用排序,这样查询的时候就能二分了

排序

我看一大堆离谱题解,这稀疏的用个map不就得了嘛

用map存语言,用结构体数组存电影(声音,字幕的语言,然后分别上map里查对应的人数,然后遍历一遍查最大值(音频更大直接换,音频相同时查字幕是不是更大))

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 200005
//int scien[maxn];
int lan[maxn];
struct movie{int aud,sub;///声音语言和字幕语言int a,b;///此音频母语人数,此字幕语言人数
}mov[maxn];
map<int,int>langer;int main()
{int n;cin>>n;int sci;for(int i=1;i<=n;i++){cin>>sci;langer[sci]++;}int m;cin>>m;for(int i=1;i<=m;i++){cin>>mov[i].aud;}for(int i=1;i<=m;i++){cin>>mov[i].sub;}movie buf;buf.a=buf.b=0;int besti=0;for(int i=1;i<=m;i++){if(langer[mov[i].aud])///存在音频{mov[i].a+=langer[mov[i].aud];}if(langer[mov[i].sub])///存在音频{mov[i].b+=langer[mov[i].sub];}if(mov[i].a>buf.a){buf=mov[i];besti=i;}else if(mov[i].a==buf.a&&mov[i].b>buf.b)///第一条件相同,比较第二条件{buf=mov[i];besti=i;///母语index}}cout<<besti<<endl;return 0;
}

v#### 小改进,加了动态开数组

malloc动态开数组时需要赋初值(也可以用memset很快的),另外还发现了上面的问题(最后一组的M<N),

这句话的m写成n了

 for(int i=1;i<=m;i++){if(langer[mov[i].aud])///存在音频{mov[i].a+=langer[mov[i].aud];}if(langer[mov[i]
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 200005
//int scien[maxn];
int lan[maxn];
struct movie{int aud,sub;///声音语言和字幕语言int a,b;///此音频母语人数,此字幕语言人数
};
map<int,int>langer;int main()
{int n;cin>>n;int sci;for(int i=1;i<=n;i++){cin>>sci;langer[sci]++;}int m;cin>>m;movie *mov=(movie*)malloc(sizeof(movie)*(m+10));memset(mov,0,sizeof(movie)*(m+10));for(int i=1;i<=m;i++){cin>>mov[i].aud;//mov[i].a=mov[i].b=0;}for(int i=1;i<=m;i++){cin>>mov[i].sub;}movie buf;buf.a=buf.b=0;int besti=0;for(int i=1;i<=m;i++){if(langer[mov[i].aud])///存在音频{mov[i].a+=langer[mov[i].aud];}if(langer[mov[i].sub])///存在音频{mov[i].b+=langer[mov[i].sub];}if(mov[i].a>buf.a){buf=mov[i];besti=i;}else if(mov[i].a==buf.a&&mov[i].b>buf.b)///第一条件相同,比较第二条件{buf=mov[i];besti=i;///母语index}}cout<<besti<<endl;return 0;
}
不对啊,应该占的内存小了啊,咋还大了,我人傻了


货仓选址

链接:https://ac.nowcoder.com/acm/problem/50937
来源:牛客网题目描述
在一条数轴上有N家商店,它们的坐标分别为 A[1]~A[N]。现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入描述:
第一行一个整数N,第二行N个整数A[1]~A[N]。
输出描述:
一个整数,表示距离之和的最小值。
示例1
输入
复制
4
6 2 9 1
输出
复制
12
备注:
对于100%的数据:N\leq 100000N≤100000, A[i]\leq 1000000A[i]≤1000000

这题我第一眼都傻了,上来就是广搜+动归ptsd,说好的早睡呢

但其实就是当处于中间两个数之间的时候,那么往左移和往右移并不影响总距离(一半全体+1另一半全体-1),而正好中间就不能动了,这也是要的是个距离和的值的原因(坐标不唯一)

也就是排个序直接求中位数(这题真的是按难度排序嘛)

细节:如果商店数为偶数的话,中点有两个商店,此时在这两个商店之间任选一点都可,即a[n/2]<=k<=a[n/2+1],因为除这两个商店外左右两边的商店数是相等的(即k向右移总距离加减数相等),而这两个商店到k的距离和又是定值,所以不影响答案,我们可以直接选择a[n/2]。
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 100005
int a[maxn];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int mid=n/2;int sum=0;for(int i=1;i<=n;i++){sum+=abs(a[i]-a[mid]);}cout<<sum;return 0;
}
另:明明是一样的代码为啥我的内存是人家一倍,,,,,,,

七夕祭P32

链接:https://ac.nowcoder.com/acm/problem/50939
来源:牛客网

七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。于是TYVJ今年举办了一次线下七夕祭。Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩。描述
TYVJ七夕祭和11区的夏祭的形式很像。矩形的祭典会场由N排M列共计N×M个摊点组成。虽然摊点种类繁多,不过cl只对其中的一部分摊点感兴趣,比如章鱼烧、苹果糖、棉花糖、射的屋……什么的。Vani预先联系了七夕祭的负责人zhq,希望能够通过恰当地布置会场,使得各行中cl感兴趣的摊点数一样多,并且各列中cl感兴趣的摊点数也一样多。不过zhq告诉Vani,摊点已经随意布置完毕了,如果想满足cl的要求,唯一的调整方式就是交换两个相邻的摊点。两个摊点相邻,当且仅当他们处在同一行或者同一列的相邻位置上。由于zhq率领的TYVJ开发小组成功地扭曲了空间,每一行或每一列的第一个位置和最后一个位置也算作相邻。现在Vani想知道他的两个要求最多能满足多少个。在此前提下,至少需要交换多少次摊点。输入描述:
第一行包含三个整数N和M和T。T表示cl对多少个摊点感兴趣。
接下来T行,每行两个整数x, y,表示cl对处在第x行第y列的摊点感兴趣。
输出描述:
首先输出一个字符串。如果能满足Vani的全部两个要求,输出both;如果通过调整只能使得各行中cl感兴趣的摊点数一样多,输出row;如果只能使各列中cl感兴趣的摊点数一样多,输出column;如果均不能满足,输出impossible。
如果输出的字符串不是impossible, 接下来输出最小交换次数,与字符串之间用一个空格隔开。
示例1
输入
复制
2 3 4
1 3
2 1
2 2
2 3
输出
复制
row 1
示例2
输入
复制
3 3 3
1 3
2 2
2 3
输出
复制
both 2

根据前几道的经验,我估计这是个数学题

交换上下和交换左右分别只影响行和列,所以可以分离

题解+均分纸牌题解
https://www.cnblogs.com/suansuan918106840226/p/12274711.html

非常有意思 原题=2个环形纸牌=2个(均分纸牌+货仓)

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int N,M,T;
#define maxn 100005
int a[maxn],b[maxn],sum[maxn];
///ab为坐标,同时也是两个需要均分的数组
int main()
{cin>>N>>M>>T;int x,y;for(int i=1;i<=T;i++){cin>>x>>y;a[x]++;b[y]++;}if(T%N!=0&&T%M!=0)///无法均分纸牌{cout<<"impossible";return 0;}for(int i=1;i<=N;i++){a[i]-=T/N;///等效的,这样可以记录需要传递的牌数}for(int i=1;i<=M;i++){b[i]-=T/M;}ll ans=0;if(T%N==0){///for(int i=1;i<=N;i++){sum[i]=sum[i-1]+a[i];///前缀和}sort(sum+1,sum+1+N);int mid=(N+1)/2;///货仓选址for(int i=1;i<=N;i++){ans+=abs(sum[i]-sum[mid]);}}if(T%M==0){///for(int i=1;i<=M;i++){sum[i]=sum[i-1]+b[i];///前缀和}sort(sum+1,sum+1+M);int mid=(M+1)/2;///货仓选址for(int i=1;i<=M;i++){ans+=abs(sum[i]-sum[mid]);}}if(T%M==0&&T%N==0)printf("both ");else if(T%M==0)printf("column ");else printf("row ");cout<<ans;return 0;
}

Running Median(还有别的解法,有空看看)

依次给出n个数字,每输入一个奇数则输出即时中位数。(共有(n+1)/2个)

对顶堆,即用两个堆,一个大根堆一个小根堆。每次比较两个堆的堆顶,如果不相等就交换堆顶,否则堆顶即为所要求的中位数。

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<cctype>inline void read(int &x)
{char c=getchar(); int f=1;x=0;while(!isdigit(c)) {if (c=='-') f=-1;c=getchar();}while(isdigit(c)) {x=x*10+c-48;c=getchar();}x*=f; return;
}
std::priority_queue <int> lq,sq;
//lq大根堆,sq小根堆
int main()
{int n,t,x,a,b,cnt;read(t);while(t--){read(cnt); read(n);while(lq.size()) lq.pop();while(sq.size()) sq.pop();printf("%d %d\n",cnt,(n+1)/2);for(int i=1;i<=n;i++){read(x);lq.push(x),sq.push(-x);if(i%2==0) continue;while(lq.top()!=-sq.top()){a=lq.top();lq.pop();b=-sq.top();sq.pop();sq.push(-a);lq.push(b);}printf("%d ",lq.top());if(((i+1)/2)%10 == 0) puts("");else if((n%2==1&&i==n)||(n%2==0&&i==n-1))puts("");}}return 0;
}

逆序对

用归并排序计算逆序对个数
l到r,

短路运算符,所以没加括号

!!归并排序逆序对模板(就记这个吧,准些)

bits/stdc++.h>
using namespace std;
const int N=501000;
#define ll long long
ll n,m,i,j,k,a[N],b[N],cnt;
void merge(ll a[],ll l,ll r)
{if (r-l<1)///等价于l==rreturn ;ll mid=(l+r)/2;merge(a,l,mid);merge(a,mid+1,r);ll i=l,j=mid+1;for (ll k=l;k<=r;k++){if (j>r || i<=mid && a[i]<=a[j])///这里有个等号b[k]=a[i++];else{cnt+=mid-i+1;b[k]=a[j++];}}for (ll k=l;k<=r;k++)a[k]=b[k];
}
int main()
{ios::sync_with_stdio(false);while(cin>>n && n){for (i=1;i<=n;i++)cin>>a[i];cnt=0;merge(a,1,n);///用的时候直接输入1到n(a[n]里也有数)cout<<cnt<<endl;}return 0;
}

Ultra-QuickSort


就是冒泡排序次数(每找到一对颠倒逆序对,都要交换一次,逆序对个数-1),也是逆序对个数

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 500005
int cnt=0;
int a[maxn],b[maxn];void my_merge(int l,int mid,int r)
{int i=l,j=mid+1;for(int k=l;k<=r;k++){if(j>r||i<=mid&&a[i]<a[j]){b[k]=a[i++];}else{b[k]=a[j++];cnt+=mid-i+1;///a[j]较小,则a[i~mid]都比a[j]大(因为归并嘛,排好之后a[j]在他们前面)}}for(int k=l;k<=r;k++){a[k]=b[k];}}
void s2(int l,int r)
{if(l==r)return ;int mid=(l+r)/2;s2(l,mid);s2(mid+1,r);my_merge(l,mid,r);
}
int main()
{int buf;int n=0;///inputwhile(cin>>n){if(n==0){break;}cnt=0;for(int i=0;i<n;i++){cin>>a[i];}s2(0,n-1);cout<<cnt<<endl;}return 0;
}

奇数码游戏

他只问行不行

空格左右移动时,逆序对个数肯定不变(因为就是正常移嘛)

上下移动时,那就是移动过去,也就是一个数和n-1个数交换位置,奇偶不变

横向展开成一位序列,计算逆序对个数

第一遍的代码,这个很离谱,不知道为什么会随机的无法输入?一会70%一会10%,纯看运气

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 500*500+5
int n;
int a[maxn],b[maxn],a2[maxn];
///int cnt1=0;
///int cnt2=0;void my_merge(int l,int mid,int r,int *yuan,int *buf)
{int i=l,j=mid+1;for(int k=l;k<=r;k++){if(j>r||i<=mid&&yuan[i]<yuan[j])///三个条件一次写错,我真的是{buf[k]=yuan[i++];}else{buf[k]=yuan[j++];///cnt1++;///写错了yuan[500*500+3]+=mid-i+1;}}for(int k=l;k<=r;k++){yuan[k]=buf[k];}
}void s2(int l,int r,int *yuan,int *buf)
{if(l==r){return ;}int mid=(l+r)/2;s2(l,mid,yuan,buf);s2(mid+1,r,yuan,buf);my_merge(l,mid,r,yuan,buf);}int main()
{int n;while(cin>>n){if(n==1){cin>>a[0];cin>>a2[0];cout<<"TAK"<<endl;continue;}//  cout<<"main1"<<endl;int buf;for(int i=0;i<n*n-1;i++){cin>>buf;if(buf==0){i--;continue;}else{a[i]=buf;}}for(int i=0;i<n*n-1;i++){cin>>buf;if(buf==0){i--;continue;}else{a2[i]=buf;}}//cout<<"main2"<<endl;a[500*500+3]=0;a2[500*500+3]=0;s2(0,n*n-1-1,a,b);s2(0,n*n-1-1,a2,b);int ji1=a[500*500+3]%2;int ji2=a2[500*500+3]%2;// cout<<"main3"<<endl;if(ji1==ji2){cout<<"TAK"<<endl;}else{cout<<"NIE"<<endl;}}return 0;
}

第二遍的代码

如果说总是要多输入几次才能行,可以在每个输入下面写输出,看看是不是循环输入次数算错了

目前出现的憨批错误

1.cnt+=mid-i+1;没写+号
2.a[m++]=buf;多写个等号结果全没输入进去
3.

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 505*505
ll cnt;
int a[maxn],b[maxn];void my_merge(int l,int mid,int r)
{int i=l,j=mid+1;for(int k=l;k<=r;k++){if(j>r||i<=mid&&a[i]<=a[j]){b[k]=a[i++];}else{b[k]=a[j++];cnt+=mid-i+1;///a[j]较小,则a[i~mid]都比a[j]大(因为归并嘛,排好之后a[j]在他们前面)}}//cout<<"*";for(int k=l;k<=r;k++){a[k]=b[k];}}
void s2(int l,int r)
{//cout<<"#";if(r-l<1)return ;int mid=(l+r)/2;s2(l,mid);s2(mid+1,r);my_merge(l,mid,r);
}
int main()
{//    ios::sync_with_stdio(0);
//    cin.tie(0);
//    cout.tie(0);int buf;int n;///inputwhile(cin>>n){if(n==1){cin>>buf;cin>>buf;cout<<"TAK"<<endl;}memset(a,0,sizeof(a));memset(b,0,sizeof(b));int m=0;for(int i=0;i<n*n;i++){cin>>buf;if(buf==0){continue;}a[m++]=buf;}ll ans1;cnt=0;s2(0,n*n-1);ans1=cnt;memset(a,0,sizeof(a));memset(b,0,sizeof(b));ll ans2;m=0;for(int i=0;i<n*n;i++){cin>>buf;if(buf==0){continue;}a[m++]=buf;}//
//        for(int i=0;i<n*n;i++)
//        {//            cout<<a[i]<<" ";
//        }//cnt=0;s2(0,n*n-1);ans2=cnt;if((ans1&1)==(ans2&1)){cout<<"TAK"<<endl;}else{cout<<"NIE"<<endl;}}return 0;
}

蓝桥备赛第二周 前缀和相关推荐

  1. 蓝桥备赛第一周2021.1.11 递归 枚举 位运算

    文章目录 递归实现指数型枚举 递归指数型枚举 方法1:肯定是2^n行,所以直接就是上一个动态m从0到n加一堆空行 方法2:以最新的值为n为结束,遇到为0的不输出,用完要恢复为0 递归实现排列型枚举 非 ...

  2. 【蓝桥备赛冲刺】2022年第十三届省赛模拟题题解C/C++

    食用该篇博客前须知: (0)第一次写博客,如有地方处理不好请见谅,后续会不断提高自己的写博客能力. (1)在头文件处偷了懒,使用的都是万能头文件.(最好还是自己要记住常用头文件 (2)使用的是C++, ...

  3. 蓝桥备赛第三周 倍增+贪心+素数+约数

    文章目录 0X06倍增 天才ACM(有空再做) 0X07贪心 防晒 将乳液按SPF从大到小,牛按minSPF从大到小排序 牛客有个题解都从小到大也过了 原理 畜栏预定 ~~按结束时间从小到大排~~ 按 ...

  4. 蓝桥备赛第四周 同余+并查集

    文章目录 0x33 同余 同余类+剩余系+费马小定理+欧拉定理及推论 最幸运的数字 题解 这次的代码很多东西:欧拉函数快速求解,gcd,快速乘,各种定理,建议当模板背 10LL 转换成长整型 快速乘+ ...

  5. 蓝桥杯训练营第二周作业

    19201419曾宇杰 1. 带分数 问题描述 100 可以表示为带分数的形式:100 = 3 + 69258 / 714. 还可以表示为:100 = 82 + 3546 / 197. 注意特征:带分 ...

  6. 【蓝桥备赛】七星填空

    题目 如下图所示.在七角星的 14 个节点上填入 1 ~ 14的数字,不重复,不遗漏. 要求每条直线上的四个数字之和必须相等. 图片描述 图中已经给出了 3 个数字. 请计算其它位置要填充的数字,答案 ...

  7. 【蓝桥杯单片机组】备赛实战问题记录

    微信搜索:ReCclay,也可免费阅读博主蓝桥系列所有文章,后台回复"代码"即可获取蓝桥所有备赛代码!关注博主公众号,还可拥有加入博主粉丝群实时沟通技术难题.免费下载CSDN资源等 ...

  8. 备赛全国阳光健身健美大赛训练记录(粗略)

    上午: 每组15次以上,冲破常规的8-12组 手臂二头+三头 手臂二头短头加强训练,半程,细节:锁紧手肘,半程 三头:下压,身体勿后仰过多,细节:一定要顶峰收缩 期间注意拉伸 三头:屈臂伸,细节:身体 ...

  9. 【蓝桥杯备赛】历年真题解答+知识点总结

    文章目录 历年真题 算法思维 1. 模拟 1.1日期处理 1.1.1 解法一:win自带的计算器 1.1.2 解法二:Excel+手算 1.1.3 解法三:代码实现 1.2 全排列 1.3 判断回文数 ...

最新文章

  1. java面试时候算法题多吗_java程序员面试中最容易被问到的18个算法题(附答案!)...
  2. 独家福利 | 科大讯飞全球1024开发者节限时免费门票!
  3. Eclipse 安装热部署JRebel
  4. 数据标准化处理,data.mean和data.std
  5. python 六边形架构_通过纯css3代码实现六边形边框
  6. 解决ScrollView嵌套ViewPager出现的滑动冲突问题
  7. 用Setup Factory打包Visual C++ 2008开发的程序心得总结
  8. mysql 举例_MySQL 语句举例(一)
  9. 微信小程序 ---- 学习目标认识小程序
  10. cmake之系统头文件(六)
  11. 数据结构与算法经典图书推荐
  12. 分享微信预约系统开发制作步骤_教你实现微信公众预约系统的方法
  13. Querydsl使用fetchCount()报错
  14. 台式计算机wifi老掉线,电脑连接WiFi容易断线或速度慢怎么回事 教你怎么解决
  15. 【树莓派初始化】教你从0开始搭建树莓派的使用环境
  16. VScode 插件中 package.json 文件字段详解
  17. 【Aegisub相关】loop修饰语实现对应的源码
  18. TypeScript类
  19. web项目引入PDF.js并添加水印禁止下载
  20. form编译报错:ORA-12162: TNS:net service name is incorrectly specified解决办法

热门文章

  1. 查看CentOS的版本信息
  2. Android之BroadcastReceiver的使用
  3. 编译原理——语言处理程序
  4. 自定义视图 视图控制器(UIViewController)
  5. Rocky(dfs)
  6. python无向加权图_图:无向图(Graph)基本方法及Dijkstra算法的实现 [Python]
  7. 修改图片背景_用P图软件将图片背景更改
  8. java异步调用数据库存储过程详解,java中如何调用存储过程
  9. python模拟登陆 验证码el_python 模拟登陆github的示例
  10. burst tx 功能 开启_Serverspeeder 锐速config配置文件详解