noip模拟37
\(\color{white}{\mathbb{燕子来时青尚在,木荫遥看杏花菲,名之以:杏红}}\)
考场发现 \(t2\) 基本上是原题,\(t3\) 的套路见过,\(t4\) 像是并查集之类的算法,\(t1\) 是个扩欧,总之感觉今天的题非常可做
先写 \(t3\) 打完二进制分组,过了大样例,然后也没测时间也没对拍开始写 \(t2\),很快也过了大样例,然后推 \(t1\),像是个三分,打完稍调一下也过了大样例。
发现时间还有两个半小时,觉得良心出题人前三题都给了大样例,估计不用对拍了吧,于是开始想 \(t4\)
想了一个小时复杂度大概对了,半个小时码完,再写个暴力挂上对拍
发现还有将近一个小时,开始喝水上厕所(一度以为有生之年可以AK了)
最后考完发现两题都挂了,发现 \(t1\) 有个三分的细节写错了,\(t3\) 是位运算弄错了,总共挂了 135 的分……
还是得认真检查……
A. 数列
很明显是扩欧,然后要求一组解使得 \(abs(x)+abs(y)\) 最小,这个是单峰函数,写了个三分,但是左右 \(mid\) 写错了
更简单的做法是令 \(a < b\),那么求通解的时候 \(x\) 每次跨度大,\(y\) 跨度小,所以当 \(abs(x)\) 小的时候一定答案最小
代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+5;
int n,a,b,g,x,y,p[maxn],ans,xx,yy,ax,ay;
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
void exgcd(int a,int b){
if(!b){
x=1;
y=0;
return ;
}
exgcd(b,a%b);
int k=y;
y=x-a/b*y;
x=k;
return ;
}
int calc(int k){
return abs(xx+k*ax)+abs(yy-k*ay);
}
int solve(int val){
if(val%g){
puts("-1");
exit(0);
}
xx=x*val/g;
yy=y*val/g;
int l=-1e9,r=1e9,lastl=0,lastr=0,cnt=0;
while(l<r){
int lmid=(r-l+1)/3+l;
int rmid=l+r-lmid;
// cout<<l<<" "<<r<<" "<<lmid<<" "<<rmid<<endl;
if(calc(lmid)<calc(rmid))r=rmid;
else l=lmid;
if(l==lastl&&r==lastr)cnt++;
else lastl=l,lastr=r,cnt=0;
if(cnt>=2)break;
}
int mn=0x3f3f3f3f3f3f3f3f;
for(int i=l-1;i<=r+1;i++){
mn=min(mn,calc(i));
}
return mn;
}
signed main(){
// freopen("array.in","r",stdin);
// cout<<gcd(12,18);
n=read();
a=read();
b=read();
g=gcd(a,b);
// cout<<g<<endl;
exgcd(a,b);
ax=b/g;
ay=a/g;
// cout<<x<<" "<<y<<endl;
for(int i=1;i<=n;i++){
p[i]=read();
}
for(int i=1;i<=n;i++){
ans+=solve(abs(p[i]));
}
cout<<ans;
return 0;
}
B. 数对
类似与队长快跑,只不过这道题无序,按 \(min(a_i,b_i)\) 排序即可
C. 最小距离
二进制拆分写错+卡常挂成零分
一定注意 \((1<< pos ) \& x\) 的值不是 \(1\)!!!!
正解是记录每个点更新的源点或者次短路
代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=4e5+5;
const int maxm=1e6+5;
int n,m,x,y,w,hd[maxn],cnt,dis[maxn],a[maxn],k,ans[maxn],col[maxn];
bool vis[maxn];
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
struct Edge{
int nxt,from,to,val;
}edge[maxm];
void add(int u,int v,int w){
edge[++cnt].nxt=hd[u];
edge[cnt].to=v;
edge[cnt].val=w;
edge[cnt].from=u;
hd[u]=cnt;
return ;
}
struct Node{
int dis,id;
Node(){}
Node(int x,int y):dis(x),id(y){}
bool operator < (const Node & x)const{
return dis>x.dis;
}
};
priority_queue<Node>q;
void dij(){
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof vis);
for(int i=1;i<=k;i++){
col[a[i]]=i;
q.push(Node(0,a[i]));
dis[a[i]]=0;
}
while(!q.empty()){
int u=q.top().id;
q.pop();
if(vis[u])continue;
vis[u]=true;
for(int i=hd[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].val){
dis[v]=dis[u]+edge[i].val;
col[v]=col[u];
q.push(Node(dis[v],v));
}
}
}
return ;
}
signed main(){
// freopen("distance.in","r",stdin);
// freopen("my.out","w",stdout);
n=read();
m=read();
k=read();
memset(ans,0x3f,sizeof ans);
for(int i=1;i<=k;i++){
a[i]=read();
}
for(int i=1;i<=m;i++){
x=read();
y=read();
w=read();
add(x,y,w);
add(y,x,w);
}
dij();
for(int i=1;i<=cnt;i++){
if(col[edge[i].from]!=col[edge[i].to]){
ans[col[edge[i].from]]=min(ans[col[edge[i].from]],edge[i].val+dis[edge[i].from]+dis[edge[i].to]);
ans[col[edge[i].to]]=min(ans[col[edge[i].to]],edge[i].val+dis[edge[i].from]+dis[edge[i].to]);
}
}
for(int i=1;i<=k;i++){
printf("%lld ",ans[i]);
}
return 0;
}
D. 真相
这种题一看类似于图论
按照真假拆点建图后发现分成多个块,每个块的结尾都是 \(1\) 类节点
那么一种思路是枚举每个结尾点,统计所有与其相同的节点的真话总数,判断是否满足即可,这个可以预处理优化成 \(O(n)\)
代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int t,n,a[maxn],val[maxn],pos[maxn],val1[maxn],tot,w[maxn],sumtot,sum1[maxn],sum2[maxn];
bool vis[maxn];
char c[5];
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
void work(){
int op=0;
for(int i=1;i<=n;i++){
op^=a[i];
}
if(op==0)puts("consistent");
else puts("inconsistent");
return ;
}
void pre(){
for(int j=1;j<=tot;j++){
int p=pos[j];
int op=0;
while(!vis[p-1]){
p--;
if(!p)p=n;
if(vis[p])break;
op^=a[p];
val[j]+=(!op);
}
val[j]++;
p=pos[j],op=1;
while(!vis[p-1]){
p--;
if(!p)p=n;
if(vis[p])break;
op^=a[p];
val1[j]+=(!op);
// cout<<p<<" "<<a[p]<<" "<<op<<endl;
}
// cout<<val[j]<<" "<<val1[j]<<endl;
}
return ;
}
bool solve(){
for(int i=1;i<=n;i++){
sum1[w[i]]+=val[i];
sum2[w[i]]+=val1[i];
sumtot+=val1[i];
}
for(int i=1;i<=tot;i++){
int sum=sumtot-sum2[w[i]]+sum1[w[i]];
if(sum==w[i])return true;
}
int sum=0;
for(int i=1;i<=tot;i++){
sum+=val1[i];
}
for(int i=1;i<=tot;i++){
if(sum==w[i])return false;
}
return true;
}
void init(){
for(int i=1;i<=n;i++){
a[i]=vis[i]=val[i]=val1[i]=sum1[i]=w[i]=sum2[i]=0;
}
tot=sumtot=0;
return ;
}
int main(){
// freopen("shuju.in","r",stdin);
// freopen("my1.out","w",stdout);
t=read();
while(t--){
init();
n=read();
for(int i=1;i<=n;i++){
scanf("%s",c+1);
if(c[1]=='$')pos[++tot]=i,vis[i]=true,w[tot]=read();
else if(c[1]=='-')a[i]=1;
else a[i]=0;
}
if(!tot){
work();
continue;
}
pre();
if(solve())puts("consistent");
else puts("inconsistent");
}
return 0;
}
\(\color{white}{\mathbb{花褪残红青杏小,燕子来时,绿水人家绕。}}\)
noip模拟37的更多相关文章
- Noip模拟37 2021.8.12
T1 数列 真是考场上不是数学的乱推柿子,想定理,是数学的没想出来.. 比较悲伤... 列柿子不用动脑子,就是没有想出来$EXgcd$解不定方程,淦.. 解处一组解后利用比较显然的性质: $x+\fr ...
- 2021.8.12考试总结[NOIP模拟37]
T1 数列 考场上切掉的简单题. $a$,$b$与数列中数的正负值对答案无关.全当作正数计算即可. $exgcd$解未知数系数为$a$,$b$,加和为$gcd(a,b)$的不定方程组,再枚举每个数.如 ...
- NOIP模拟 37
啊哈这次没什么智障低错丢rank什么的托词了STO 发现好像110我就拿满了.. 水平不行..只会简单题qaq T1 可以树上启发式合并水过(普通分治也行) T2 我连那么显然的 一劳永逸的容斥都没想 ...
- 812考试总结(NOIP模拟37)[数列·数对·最小距离·真相]
前言 考得挺憋屈的... 先是搞了两个半小时的 T1 后来发现假了,又没多想跳了.. 然后一看 T2 这不是队长快跑嘛... 先是根据自己的想法打了一遍(考完之后发现是对的..) 然后回想了一下之前的 ...
- NOIP模拟17.9.22
NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥
- NOIP 模拟4 T2
本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...
- noip模拟32[好数学啊]
noip模拟32 solutions 真是无语子,又没上100,无奈死了 虽然我每次都觉得题很难,但是还是有好多上100的 战神都200多了,好生气啊啊啊 从题开始变难之后,我的时间分配越来越不均匀, ...
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
随机推荐
- Go语言常见的坑
目录 1. 可变参数是空接口类型 2. 数组是值传递 3.map遍历是顺序不固定 4. 返回值被屏蔽 5.recover必须在defer函数中运行 6. main函数提前退出 7.通过Sleep来回避 ...
- 群晖NAS网络存储服务器防盗防小偷
群晖NAS网络存储服务器防盗防小偷 根据群晖NAS的实际测量外形尺寸到淘宝网邮购金属 配电箱(弱电箱). 把配电箱(弱电箱)用粗螺丝固定到机柜或墙壁上. 把群晖NAS用密码纯铜挂锁锁在配电箱(弱电箱 ...
- Python实现猜数字游戏
Python中实现猜数字游戏代码如下: import random # 引入随机数标准库-random # 定义数字上下限和最大游戏次数 min_num = 1 max_num = 10 guess_ ...
- 面试利器!字节跳动2021年Android程序员面试指导小册已开源
整份手册分为两个部分,分别是:Java部分.Android部分.数据结构与算法篇.字节跳动2020年全年面试题总结篇! 每个知识点都有左侧导航书签页,看的时候十分方便,由于内容较多,这里就截取一部分图 ...
- Linux下使用pure-ftpd建立匿名ftp访问
by 无若 (一)ubuntu14.04下使用pure-ftpd建立匿名ftp访问 1.安装apt-get install pure-ftpd 2.修改配置nano /etc/pure-ftpd/co ...
- MapReduce框架-Join的使用
引言 首先先明白在关系型数据库中Join的用法. Join在MapReduce中的用法也是用于两个文件之间的连接. 使用MR程序解决两张表的join问题,有两种解决方案 à MR程序的join应用 1 ...
- 别再用CSV了,更高效的Python文件存储方案
CSV无可厚非的是一种良好的通用文件存储方式,几乎任何一款工具或者编程语言都能对其进行读写,但是当文件特别大的时候,CSV这种存储方式就会变得十分缓慢且低效.本文将介绍几种在Python中能够代替CS ...
- linux的iptables设置
添加规则 -A 在链末尾追加一条规则 -I 在链开头或某序号前插入一条规则 查看规则 -L 列出所有规则 -n 数字显示地址和端口信息 -v 详细信息 -line-numbers 显示规则序号 删除规 ...
- gRPC学习之五:gRPC-Gateway实战
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 如何不耍流氓的做运维之-SHELL脚本
前言 大家都是文明人,尤其是做运维的,那叫一个斯文啊.怎么能耍流氓呢?赶紧看看,编写SHELL脚本如何能够不耍流氓. 下面的案例,我们以MySQL数据库备份SHELL脚本的案例来进行阐述: 不记录日志 ...