Codeforces Round #618 (Div. 2)
A. Non-zero (CF 1300 A)
题目大意
给定个数。有一种操作,选择一个数使之加一。现要求这个数的和和积均不为0,问最少的操作次数。
解题思路
有加,最后和为的话,因为每个数都不是,所以必有正也有负,此时再随便找一个正数加即可。
神奇的代码
#include <bits/stdc++.h> #define MIN(a,b) ((((a)<(b)?(a):(b)))) #define MAX(a,b) ((((a)>(b)?(a):(b)))) #define ABS(a) ((((a)>0?(a):-(a)))) using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; typedef vector<PII> VPII; typedef vector<LL> VL; typedef pair<LL,LL> PLL; typedef vector<PLL> VPLL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int main(void) { int kase; read(kase); for (int i = 1; i <= kase; i++) { int n; read(n); int a[n+1]={0}; int sum=0; int ans=0; for(int i=1;i<=n;++i){ read(a[i]); if (a[i]==0) ++a[i],++ans; sum+=a[i]; } if (sum==0) ++ans; write(ans,'\n'); } return 0; }
B. Assigning to Classes (CF 1300 B)
题目大意
个数要求分成两组,使两个组的中位数相差最小,问最小差。
解题思路
很容易看出答案就是这个数排好序后第个数和第个数的差值。
神奇的代码
#include <bits/stdc++.h> #define MIN(a,b) ((((a)<(b)?(a):(b)))) #define MAX(a,b) ((((a)>(b)?(a):(b)))) #define ABS(a) ((((a)>0?(a):-(a)))) using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; typedef vector<PII> VPII; typedef vector<LL> VL; typedef pair<LL,LL> PLL; typedef vector<PLL> VPLL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int main(void) { int kase; read(kase); for (int i = 1; i <= kase; i++) { int n; read(n); n<<=1; int a[n]; for(int i=0;i<n;++i) read(a[i]); sort(a,a+n); int ans=a[n/2]-a[n/2-1]; write(ans,'\n'); } return 0; }
C. Anu Has a Function (CF 1300 C)
题目大意
有一函数(是或运算并不是整除),现有个数,要求安排一种顺序,使得结果最大。
解题思路
注意到函数可以等效为一种位运算,,对于的每一个是的位,如果对应位为则变成,否则则不改变。所以一旦我们确定了第一个数,剩下的数的顺序是无关紧要的。我们统计每个数在二进制下所在的位数,最后从高到低看哪一位的只有一个数有,就把那个数放在第一位,其他的数随便输出就好了。因为如果出现次数是及以上的话会被消掉。
神奇的代码
#include <bits/stdc++.h> #define MIN(a,b) ((((a)<(b)?(a):(b)))) #define MAX(a,b) ((((a)>(b)?(a):(b)))) #define ABS(a) ((((a)>0?(a):-(a)))) using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; typedef vector<PII> VPII; typedef vector<LL> VL; typedef pair<LL,LL> PLL; typedef vector<PLL> VPLL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int main(void) { int n; read(n); int a[n]; int cnt[35]; memset(cnt,0,sizeof(cnt)); for(int i=0;i<n;++i) { read(a[i]); int qwq=a[i]; int id=0; while(qwq){ cnt[id++]+=(qwq&1); qwq>>=1; } } int id=35; while(id>=0&&cnt[id]!=1) --id; if (id==-1) for(int i=0;i<n;++i) printf("%d%c",a[i],i==n-1?'\n':' '); else{ for(int i=0;i<n;++i) if ((a[i]>>id)&1){id=i;break;} printf("%d ",a[id]); for(int i=0;i<n;++i) if (i==id) continue; else printf("%d ",a[i]); } return 0; }
D. Aerodynamic (CF 1300 D)
题目大意
以给端点坐标的形式给定一个多凸边形,定义一种线性变换表示将多边形分别沿轴方向平移个单位,沿轴方向平移个单位后的多边形。定义是一连串符合条件的多边形的并集,条件是原点在的边上或里面,问与是否相似。
解题思路
读题读了好多遍才明白……原本没有什么头绪的然后我打开几何画板把样例三的图形画出来后。
我有一个大胆的想法。
如果是奇多边形肯定不相似,偶多边形的话,就看它对边是否平行且相等。(点与点所形成的边与点与点所形成的边)
(猜题大法好)
神奇的代码
#include <bits/stdc++.h> #define MIN(a,b) ((((a)<(b)?(a):(b)))) #define MAX(a,b) ((((a)>(b)?(a):(b)))) #define ABS(a) ((((a)>0?(a):-(a)))) using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; typedef vector<PII> VPII; typedef vector<LL> VL; typedef pair<LL,LL> PLL; typedef vector<PLL> VPLL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int main(void) { int n; read(n); pair<int,int> point[n]; for(int x,y,i=0;i<n;++i){ read(x); read(y); point[i]=make_pair(x,y); } if (n&1) puts("NO"); else{ bool qwq=true; for(int j=0,i=n/2;i<n;++i,++j){ if (!qwq) break; if (point[j].first-point[j+1].first!=point[(i+1)%n].first-point[i].first) qwq=false; if (point[j].second-point[j+1].second!=point[(i+1)%n].second-point[i].second) qwq=false; } if (qwq) puts("YES"); else puts("NO"); } return 0; }
E. Water Balance (CF 1300 E)
题目大意
给定一个有个数的序列,有一种操作,选择两个数,然后将区间的数替换成这个区间的平均数。可以进行任意多次操作,问最后能得到的字典序最小的序列是怎样的。
解题思路
我们注意到一个重要性质:最终序列的数一定是递增的。因为如果有前一个数大于后一个数,那么我们把那个范围取个平均值,得到的是一个字典序更小的序列。所以我们就从左到右依次把每个数添加进去,如果这个数小于前一个我们已经平均的平均数,那么我们就把这个数也加入到前一个平均的范围内,重复即可。
神奇的代码
#include <bits/stdc++.h> #define MIN(a,b) ((((a)<(b)?(a):(b)))) #define MAX(a,b) ((((a)>(b)?(a):(b)))) #define ABS(a) ((((a)>0?(a):-(a)))) using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; typedef vector<PII> VPII; typedef vector<LL> VL; typedef pair<LL,LL> PLL; typedef vector<PLL> VPLL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int main(void) { int n; read(n); LL a[n+1]={0}; for(int i=1;i<=n;++i) read(a[i]); pair<pair<LL,LL>,int> qwq[n+1]; int cnt=0; qwq[0]=(make_pair(make_pair(a[1],1),1)); for(int i=2;i<=n;++i){ if (qwq[cnt].first.first>=(LL)qwq[cnt].first.second*a[i]){ qwq[cnt]=make_pair(make_pair(qwq[cnt].first.first+a[i],qwq[cnt].first.second+1),i); while(cnt>0&&qwq[cnt].first.first*qwq[cnt-1].first.second<=qwq[cnt-1].first.first*qwq[cnt].first.second) qwq[cnt-1]=make_pair(make_pair(qwq[cnt].first.first+qwq[cnt-1].first.first,qwq[cnt].first.second+qwq[cnt-1].first.second),qwq[cnt].second),--cnt; } else qwq[++cnt]=make_pair(make_pair(a[i],1),i); } cnt=0; for(int i=1;i<=n;++i){ printf("%.9f\n",(double)qwq[cnt].first.first/(double)qwq[cnt].first.second); if (qwq[cnt].second==i) ++cnt; } return 0; }
本文作者:~Lanly~
本文链接:https://www.cnblogs.com/Lanly/p/12292092.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步