Atcoder Grand Contest 032
打的第一场Atcoder,已经知道会被虐得很惨,但没有想到竟然只做出一题……
思维急需提升。
这题还是很签到的。
感觉正着做不好做,我们反着来,把加数变为删数。
显然每次有多个可以删时要删最后一个可删的,这样前面仍然合法,后面也有可能有更多合法情况。
发现不能删时就puts("-1")。
#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define sz 233
}
using namespace my_std;
int n;
vector<int>v;
int ans[sz];
int main()
{
cin>>n;
int x;
rep(i,1,n) cin>>x,v.push_back(x);
drep(i,n,1)
{
bool flg=0;
drep(j,i-1,0) if (v[j]==j+1) {flg=1;ans[i]=j+1;v.erase(v.begin()+j);break;}
if (!flg) return puts("-1"),0;
}
rep(i,1,n) printf("%d\n",ans[i]);
return 0;
}
首先手玩出n=3,4,5的情况。
观察一下图,发现\(n=3\)时\((1,2)\)未连边,\(n=4\)时\((1,4),(2,3)\)未连边,\(n=5\)时\((1,4),(2,3)\)未连边。
\(1+2=3,1+4=2+3=5\)。
猜一下结论,发现很容易证明,就做完了。
#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
}
using namespace my_std;
int main()
{
int n;
cin>>n;
vector<pii>v;
rep(i,1,n) rep(j,i+1,n) if (i+j!=n+(!(n&1))) v.push_back(MP(i,j));
printf("%d\n",(int)v.size());
rep(i,0,(int)v.size()-1) printf("%d %d\n",v[i].fir,v[i].sec);
return 0;
}
这题感觉好神仙啊……怎么可能做得出啊……我菜死了啊……
首先原图显然要存在一条欧拉回路,也就是度数全都为偶数。
如果有一个点的度数大于等于6,那么以它为起点,可以至少拆出3个欧拉回路,满足条件。
除去上面的情况,如果有大于等于3个点的度数为4,那么画画图会发现也是合法的。
除去上面的情况,如果有2个点度数为4而且它们之间恰好有2条路径,那么也是合法的。
除去以上情况,全都不合法。
然而考试时怎么敢那么肯定啊!!
#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 101010
typedef long long ll;
typedef double db;
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
}
using namespace my_std;
int n,m;
struct hh{int t,nxt;}edge[sz<<1];
bool vis[sz];
int head[sz],ecnt;
int deg[sz];
void make_edge(int f,int t)
{
edge[++ecnt]=(hh){t,head[f]};
head[f]=ecnt;
edge[++ecnt]=(hh){f,head[t]};
head[t]=ecnt;
++deg[f],++deg[t];
}
void out(string s){cout<<s;exit(0);}
int p1,p2;
int e;
int dfs(int x,bool t)
{
if (x==p1&&!t) return 1;
if (x==p2) return ++e,2;
#define v edge[i].t
go(x) if (!vis[(i+1)>>1])
{
vis[(i+1)>>1]=1;
int r=dfs(v,0);
if (r==1&&x!=p1) return 1;
if (r==2&&x!=p1) return 2;
}
#undef v
return 0;
}
int main()
{
read(n,m);
int x,y;
rep(i,1,m) read(x,y),make_edge(x,y);
rep(i,1,n) if (deg[i]&1) out("No");
rep(i,1,n) if (deg[i]>=6) out("Yes");
int cnt=0;vector<int>v;
rep(i,1,n) if (deg[i]==4) ++cnt,v.push_back(i);
if (cnt>=3) out("Yes");
if (cnt<=1) out("No");
p1=v[0],p2=v[1];
dfs(p1,1);
out((e==2)?"Yes":"No");
return 0;
}
容易想到把旋转看作把一个数往左边/右边插入。
但插入后其他数的位置会改变,不好处理。
考虑把位置由整数域扩展为实数域,这样其他数就可以不用改变位置了。
然后就可以DP了。设\(dp_{i,j}\)表示前\(i\)个数在数轴上单调递增,第\(i\)个数处于\([j,j+1)\)内,所需的最小代价,转移方程显然。
用前缀最小值优化一下即可。
#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define templ template<typename T>
#define sz 5050
typedef long long ll;
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
}
using namespace my_std;
int n;
ll A,B;
int pos[sz];
ll dp[sz][sz],mn[sz][sz];
int main()
{
read(n,A,B);
int x;
rep(i,1,n) read(x),pos[x]=i;
memset(dp,0x3f,sizeof(dp));memset(mn,0x3f,sizeof(mn));
rep(i,0,n) dp[0][i]=mn[0][i]=0;
rep(i,1,n) rep(j,0,n)
{
if (pos[i]==j) dp[i][j]=min(mn[i-1][j-1],dp[i-1][j]+A);
else if (pos[i]>j) dp[i][j]=mn[i-1][j]+B;
else dp[i][j]=mn[i-1][j]+A;
mn[i][j]=min(dp[i][j],j?mn[i][j-1]:ll(1e15));
}
cout<<mn[n][n];
return 0;
}
使劲找规律,发现最优解一定是中间一个分界线,左边1k,2k-1,...全都不超过m,右边同样k+1n+n,k+2n+n-1,...,全都超过m。
这个规律也不是很难证明(吧,也许我思维不够严谨)。
然后还发现分界线越往左,左边就更容易合法,右边更容易不合法,(在合法情况下)答案更小。
然后就可以二分最左的分界点了。
#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define sz 101010
}
using namespace my_std;
int n,m;
int a[sz<<1];
bool check(int p)
{
rep(i,p+1,n+n) if (a[i]+a[n+n-i+p+1]<m) return 0;
return 1;
}
int calc(int p)
{
int ret=0;
rep(i,1,p) ret=max(ret,a[i]+a[p-i+1]);
rep(i,p+1,n+n) ret=max(ret,a[i]+a[n+n-i+p+1]-m);
return ret;
}
int main()
{
cin>>n>>m;
rep(i,1,n*2) scanf("%d",&a[i]);
sort(a+1,a+n+n+1);
int l=0,r=n,pos;
while (l<=r)
{
int mid=(l+r)>>1;
if (check(mid*2)) pos=mid,r=mid-1;
else l=mid+1;
}
cout<<calc(pos*2);
return 0;
}
E看起来好难,弃了qwq。
Atcoder Grand Contest 032的更多相关文章
- Atcoder Grand Contest 032 E - Modulo Pairing(乱搞+二分)
Atcoder 题面传送门 & 洛谷题面传送门 神仙调整+乱搞题. 首先某些人(including me)一看到最大值最小就二分答案,事实上二分答案对这题正解没有任何启发. 首先将 \(a_i ...
- AtCoder Grand Contest 032 A - Limited Insertion( 思维)
Time Limit: 2 sec / Memory Limit: 1024 MB Score : 400400 points Problem Statement Snuke has an empty ...
- AtCoder Grand Contest 032 B - Balanced Neighbors——构造
题意 B - Balanced Neighbors 给定一个整数 $N$($3\leq N \leq 100$),构造一个顶点编号为 $1...N$ 的无向图,需满足如下两个条件: 简单图且连通 存在 ...
- AtCoder Grand Contest 012
AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...
- AtCoder Grand Contest 011
AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...
- AtCoder Grand Contest 031 简要题解
AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...
- AtCoder Grand Contest 010
AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...
- AtCoder Grand Contest 009
AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...
- AtCoder Grand Contest 008
AtCoder Grand Contest 008 A - Simple Calculator 翻译 有一个计算器,上面有一个显示按钮和两个其他的按钮.初始时,计算器上显示的数字是\(x\),现在想把 ...
随机推荐
- hMailServer配置图文详细教程
https://www.hmailserver.org/viewtopic.php?f=4&t=6
- php函数 array_chunk
array_chunk ( array $array , int $size [, bool $preserve_keys = false ] ) : array 将一个数组分割成多个数组,其中每个数 ...
- 第一章· Redis入门部署及持久化介绍
Redis简介 Redis安装部署 Redis持久化 Redis简介 软件说明: Redis是一款开源的,ANSI C语言编写的,高级键值(key-value)缓存和支持永久存储NoSQL数据库产品. ...
- c指针作业(第一次)
1. 数据类型的本质是什么? (从编译器的角度考虑) 数据类型可理解为创建变量的模具:是固定内存大小的别名 数据类型的作用:编译器预算对象(变量)分配的内存空间大小 注意:数据类型只是模具,编译器并没 ...
- tomcat知识(一)
1.tomcat配置javaWeb项目常见错误: ①:端口占用 ②:未配置JAVA_HOME环境变量 2.tomcat修改端口号 tomcat安装路径下面找到conf文件夹,修改server.xml文 ...
- 雷军微博拧螺丝,CFO为粉丝数发愁
导读 小米集团联合创始人.品牌战略官黎万强4年前写的书<参与感>,估计又要热卖了. 3月24日,小米CFO周受资发微博,“我刚接受了同事的挑战,要在一定时间内在微博上有更多的粉丝”,并向粉 ...
- Windows Server 2016激活方法+密钥+遇到的问题及解决办法(摘抄)
Windows Server 2016激活方法+密钥+遇到的问题及解决办法 2018年08月30日 13:47:34 Brozer 阅读数:28667 这两天公司准备部署Revit Server ...
- edusoho -A5: AppBundle UML
edusoho -A5: AppBundle UML
- 【模板】2-SAT 问题
[传送门] 分析 按照逻辑关系建图,跑tarjan,如果上下点在一个环中,说明不可能,不然就可能. 代码 #include <bits/stdc++.h> #define ll long ...
- 【转】Esp8266学习之旅① 搭建开发环境,开始一个“hellow world”串口打印。
@2019-02-28 [小记] Esp8266学习之旅① 搭建开发环境,开始一个“hellow world”串口打印.