博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AtCoder Grand Contest 032
阅读量:5297 次
发布时间:2019-06-14

本文共 5442 字,大约阅读时间需要 18 分钟。

  A:倒序考虑,每次删除最后一个合法数即可,正确性显然。好久没有atcoder比赛我又忘了评测机并没有define online_judge白交了一发。

#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define N 110 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}int gcd(int n,int m){return m==0?n:gcd(m,n%m);}int read(){ int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f;}int n,a[N],ans[N];signed main(){ n=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=n;i>=1;i--) for (int j=i;j>=1;j--) if (a[j]==j) { for (int k=j;k

  B:容易发现当n%4==0时,可以将图划分成一个二分图,使其两边和相等,然后中间所有边都连上即可。类似的可以发现,只要将图划分成若干和相同的集合即可。那么根据n的奇偶性讨论一下就好了,偶数时小的和大的两两匹配,奇数时把n单独列为一个集合同样两两匹配。

#include
#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define N 110 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}int gcd(int n,int m){return m==0?n:gcd(m,n%m);}int read(){ int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f;}int n;vector
a[N];signed main(){ n=read(); int s=n*(n+1)/2; if (n%2==0) for (int i=1;i<=n/2;i++) a[i].push_back(i),a[i].push_back(n-i+1); if (n%2==1) { for (int i=1;i<=n/2;i++) a[i].push_back(i),a[i].push_back(n-i); a[(n+1)/2].push_back(n); } int ans=0; for (int i=1;i<=(n+1)/2;i++) for (int j=i+1;j<=(n+1)/2;j++) if (i!=j) ans+=a[i].size()*a[j].size(); cout<
<

  C:首先显然必须得存在欧拉回路。那么即要把跑出来的欧拉回路拆成三个回路。显然在欧拉回路所经过的点序列中,找到一个首尾点均相同的段抽出来,就是一个回路。那么检查序列中是否有点出现三次或以上,若有显然有解;否则检查出现两次的点,这样的点需要有两个或以上,如果其中两个点能构成不相交的段则有解。注意到若有至少三个点一定有解,稍微讨论一下即可证明。那么只需要考虑有两个点的情况,判一下是否相交。实际上并不需要跑欧拉回路,通过度数讨论一下即可。

#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define N 100010#define id(i) (((i)+1)/2)char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}int gcd(int n,int m){return m==0?n:gcd(m,n%m);}int read(){ int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f;}int n,m,p[N],degree[N],cnt[N],t,stk[N<<1],top,tot;struct data{int to,nxt;}edge[N<<1];bool flag[N];void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}void dfs(int k,int t){ if (k==t) {tot++;return;} flag[k]=1; for (int i=p[k];i;i=edge[i].nxt) if (!flag[edge[i].to]||edge[i].to==t) { dfs(edge[i].to,t); }}signed main(){ n=read(),m=read(); for (int i=1;i<=m;i++) { int x=read(),y=read(); degree[x]++,degree[y]++; addedge(x,y),addedge(y,x); } for (int i=1;i<=n;i++) if (degree[i]&1) {cout<<"No";return 0;} for (int i=1;i<=n;i++) if (degree[i]>=6) {cout<<"Yes";return 0;} int cnt=0; for (int i=1;i<=n;i++) if (degree[i]>=4) {cnt++;} if (cnt>=3) {cout<<"Yes";return 0;} if (cnt<=1) {cout<<"No";return 0;} int x=0,y=0;for (int i=1;i<=n;i++) if (degree[i]>=4) if (x) y=i;else x=i; dfs(x,y); if (tot==2) cout<<"Yes";else cout<<"No"; return 0; //NOTICE LONG LONG!!!!!}

  D:将移动序列看成移动一个数,进一步看成将一个数放到一个实数位置上,代价根据是向左还是向右还是不动不同。这样dp就很显然了,即将所有数从小到大排序(相同的数按初始位置排序)后,设f[i][j]为第i个数放在第j段时,前i个数的最小代价,转移显然。

#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define N 5010#define inf 1000000000000000llchar getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}int gcd(int n,int m){return m==0?n:gcd(m,n%m);}int read(){ int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f;}int n,A,B;struct data{ int x,y; bool operator <(const data&a) const { return x
>1)==a[i].y?0:((j+1>>1)
>1)

  E:如果不考虑%m的话显然小的和大的配对。可以证明若将需要减m的对和不需要减m的对分成两组,一定存在最优方案使得不需要减m的是一段前缀而需要减m的是一段后缀,并且其分别满足上述贪心策略。具体讨论几种情况可以发现交换不会更劣。显然前后缀的分界点确定则方案确定,注意到分界点移动时两边答案单调移动且方向相同,那么二分找到最靠前的合法分界点(即满足上述条件)即可。

#include
#include
#include
#include
#include
#include
using namespace std;#define ll long long#define N 200010 #define inf 2000000001char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}int gcd(int n,int m){return m==0?n:gcd(m,n%m);}int read(){ int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f;}int n,m,a[N],ans;int calc_head(int k){ int s=0; for (int i=1;i<=k/2;i++) { if (a[i]+a[k-i+1]>=m) return inf; s=max(s,a[i]+a[k-i+1]); } return s;}int calc_tail(int k){ int s=0; for (int i=k;i<=n;i++) { if (a[i]+a[n-(i-k)]
>1; if (calc_tail(mid*2+1)==inf) L=mid+1; else R=mid-1,x=mid*2; } cout<

  F:咕

  result:rank 177 rating +46

转载于:https://www.cnblogs.com/Gloid/p/10604980.html

你可能感兴趣的文章
apache自带压力测试工具ab的使用及解析
查看>>
Android基础入门教程——8.1.2 Android中的13种Drawable
查看>>
C语言作业3
查看>>
.Net Core中的通用主机(二)——托管服务
查看>>
C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
查看>>
koogra--Excel文件读取利器
查看>>
ASP.NET 使用ajaxupload.js插件出现上传较大文件失败的解决方法
查看>>
jenkins搭建
查看>>
C#中使用Split分隔字符串的技巧
查看>>
(springboot)freemarker(二)
查看>>
linux下golang gRPC配置详解
查看>>
mongodb 简单使用说明
查看>>
eclipse的调试方法的简单介绍
查看>>
OneAPM 云监控部署与试用体验
查看>>
加固linux
查看>>
wget 升级
查看>>
为什么需要大数据安全分析?
查看>>
day13.字典复习
查看>>
IPSP问题
查看>>
(转)Java中的String为什么是不可变的? -- String源码分析
查看>>