对于虚伪而言,真实的光明或许过于耀眼了

前言

这一次吧,考得特别烂,主要是这次考试想搞一下特殊性质,然后一不小心就因小失大弄巧成拙了下,下次注意吧。。

T1 入阵曲

暴力

思路

对于这个题的话,暴力的话55pts是没有问题的,无非是二维前缀和优化一下。

然后针对于特殊性质我们可以再骗到20pts,我们发现矩形是否整除 K 是与矩阵内的数字和矩形的边长是有关系的,接下来暴力扫就可以了。。

有一个比较遗憾的地方就是这个题考试的时候搞了1.5h,但是码最基础的暴力实际上只用了20min,然后对于特殊性质搞了挺长时间,主要是搞因数那一块思路错了,最后对于这个特殊性质草草地打了上面那个暴力就走了。。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=4e2+10;
int n,m,ans,temp,mod,h[N][N],z[N][N],s[N][N],t[N][N];
int cnt,ys[N];
bool flag;
void check()
{
/*
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cout<<t[i][j]<<' ';
cout<<endl;
}
// */
freopen("date.in","r",stdin);
// freopen("date.out","w",stdout);
}
inline void work(int x,int y)
{
for(int i=1;i<=x;i++)
for(int j=1;j<=y;j++)
if((t[x][y]-t[i-1][y]-t[x][j-1]+t[i-1][j-1])%mod==0)
ans++;
}
inline void solve_1()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
h[i][j]=h[i][j-1]+s[i][j];
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
z[i][j]=z[i][j-1]+s[j][i];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
t[i][j]=t[i][j-1]+z[j][i];
// check();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
work(i,j);
}
inline void solve_2()
{
if(mod%temp==0)
mod/=temp;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(i*j%mod==0)
ans+=(n-i+1)*(m-j+1);
}
#undef int
int main()
{
#define int register long long
#define ll long long
// check();
scanf("%lld%lld%lld",&n,&m,&mod);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%lld",&s[i][j]);
temp=s[1][1];
if(s[i][j]!=temp)
flag=true;
}
if(flag) solve_1();
else solve_2();
printf("%lld",ans);
return 0;
}

正解

思路

对于正解就是在先前暴力的思路上优化,发现在\(\bmod k\)的意义下相同的前缀和任意取两个枚举相减一定是 k 的倍数了。

因此我们枚举每一行以及他下面的行,然后再枚举列,对于不同的\(\bmod k\)余数记录并且更新就好了,最后注意清空就好了。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=4e2+10,M=1e6+10;
int n,m,ans,mod,cnt[M],tmp[N],z[N][N],s[N][N],t[N][N];
inline void init()
{
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
z[i][j]=z[i][j-1]+s[j][i];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
t[i][j]=(t[i][j-1]+z[j][i])%mod;
}
#undef int
int main()
{
#define int register long long
#define ll long long
scanf("%lld%lld%lld",&n,&m,&mod);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%lld",&s[i][j]);
init();
for(int i=0;i<n;i++)
for(int j=i+1;j<=n;j++)
{
cnt[0]=1;
for(int k=1;k<=m;k++)
{
tmp[k]=(t[j][k]-t[i][k]+mod)%mod;
ans+=cnt[tmp[k]];
cnt[tmp[k]]++;
}
for(int k=1;k<=m;k++)
cnt[tmp[k]]=0;
}
printf("%lld",ans);
return 0;
}

T2 将军令

暴力

思路

其实吧,这个题比上一个题还要遗憾。。

对于本题的暴力,直接dfs就好,但是考试的时候一开始想的是在树上直接进行的dfs,然后发现深度搜索好像压根就不行。。。

于是我们用将近1h换来了几乎0pts,然后考虑更改dfs思路。

想到一个比较妙的方法,我们不是在树上进行dfs,而是对于可以覆盖到的驿站,以及有小队的驿站的数量进行深搜,然后对于每一个没有过小队的点进行尝试。

  • 注意:一定要在加小队的同时,扩散可以覆盖到的驿站,并及时进行回溯,不然就会5pts(code)

然后我们考虑特殊性质,发现对于所有节点到1距离不超过2的情况我们直接在1节点加入小队,在有子节点的深度为1的节点处加小队就好了。

暴力+特殊性质共计50pts。

当然,如果你打过小胖守皇宫这个题的话,对于k=1的情况也是50pts(反正我是一点都不记得了。。)

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,M=N<<1,INF=1e9;
int n,m,ans=INF,task,dep[N],f[N][20];
vector<int> v[N];
bool vis[N],vis1[N];
struct Edge
{
int tot,head[N],nxt[M],ver[M];
void add(int x,int y)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
}e;
void check()
{
freopen("date.in","r",stdin);
// freopen("date.out","w",stdout);
}
void dfs(int x,int fa)
{
dep[x]=dep[fa]+1;
f[x][0]=fa;
for(int i=0;f[x][i];i++)
f[x][i+1]=f[f[x][i]][i];
for(int i=e.head[x];i;i=e.nxt[i])
if(e.ver[i]!=fa)
dfs(e.ver[i],x);
}
int LCA(int x,int y)
{
if(x==y)
return x;
if(dep[x]>dep[y])
x^=y^=x^=y;
for(int i=20;i>=0;i--)
if(dep[f[y][i]]>=dep[x])
y=f[y][i];
if(x==y)
return x;
for(int i=20;i>=0;i--)
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
return f[x][0];
}
int dist(int x,int y)
{
return dep[x]+dep[y]-2*dep[LCA(x,y)];
}
void dfs1(int tot,int cnt)
{
if(cnt>n)
return ;
if(tot>=n)
{
ans=min(ans,cnt);
return ;
}
if(cnt>=ans)
return ;
vector<int > vi;
for(int i=1;i<=n;i++)
{
if(vis[i])
continue;
bool temp=vis1[i];
vis[i]=vis1[i]=true;
vi.clear();
for(int j=1;j<=n;j++)
{
if(vis1[j])
continue;
for(int k=0;k<v[j].size();k++)
if(vis[v[j][k]])
{
vis1[j]=true;
tot++;
vi.push_back(j);
break;
}
}
dfs1(tot+(!temp),cnt+1);
tot-=vi.size();
vis[i]=false;
vis1[i]=temp;
for(int j=0;j<vi.size();j++)
vis1[vi[j]]=false;
}
}
void solve_1()
{
dfs(1ll,0ll);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
int dis=dist(i,j);
if(dis<=m)
{
v[i].push_back(j);
v[j].push_back(i);
}
}
dfs1(0ll,0ll);
}
void solve_2()
{
// /*
dfs(1,0);
int flag=0;
int sum=0;
for(int i=2;i<=n;i++)
if(dep[i]==2&&e.nxt[e.head[i]])
sum++;
ans=sum+1;
// */
// ans=2;
}
#undef int
int main()
{
#define int register long long
#define ll long long
scanf("%lld%lld%lld",&n,&m,&task);
for(int i=1,x,y;i<n;i++)
{
scanf("%lld%lld",&x,&y);
e.add(x,y);
e.add(y,x);
}
if(!m) ans=n;
else if(task!=2) solve_1();
else solve_2();
printf("%lld",ans);
return 0;
}

正解

思路

消防局的设立亿些相似。

正解是贪心,首先对于深度从大到小排序,用dis数组记录距离这个点最近的有小队的驿站的数量。

如果一个点的dis大于k,那么我们直接在他的第k级祖先加入小队,然后更新深度更小的节点的dis值就好了。

最后统计一下dis为0的节点数就是答案了。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,M=N<<1,INF=1e9;
int n,m,ans,task,id[N],dep[N],fa[N],dis[N],f[N];
struct Edge
{
int tot,head[N],nxt[M],ver[M];
void add(int x,int y)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
}e;
void dfs(int x,int fat)
{
dep[x]=dep[fat]+1;
fa[x]=fat;
for(int i=e.head[x];i;i=e.nxt[i])
if(e.ver[i]!=fat)
dfs(e.ver[i],x);
}
bool comp(int x,int y)
{
return dep[x]>dep[y];
}
#undef int
int main()
{
#define int register long long
#define ll long long
scanf("%lld%lld%lld",&n,&m,&task);
fill(dis+0,dis+n+1,INF);
for(int i=1,x,y;i<n;i++)
{
scanf("%lld%lld",&x,&y);
e.add(x,y);
e.add(y,x);
}
for(int i=1;i<=n;i++)
id[i]=i;
dfs(1ll,0ll);
sort(id+1,id+n+1,comp);
for(int i=1;i<=n;i++)
{
int cnt=0,x=id[i];
if(dis[x]<=m)
continue;
f[0]=x;
while(cnt<m&&f[cnt])
{
f[cnt+1]=fa[f[cnt]];
cnt++;
if(f[cnt])
dis[x]=min(dis[x],dis[f[cnt]]+cnt);
}
if(!f[cnt])
cnt=max(cnt-1,0ll);
if(dis[x]>m)
{
dis[f[cnt]]=0;
int fat=f[cnt],sum=0;
while(fat&&sum<=m)
{
dis[fat]=min(dis[fat],sum);
fat=fa[fat];
sum++;
}
}
}
for(int i=1;i<=n;i++)
if(!dis[i])
ans++;
printf("%lld",ans);
return 0;
}

T3 星空

解题思路

对于暴力就不多讲了,骗一下\(ans \le 4\)的分就好了,多了也骗不到。。

正解思路非常妙,官方的题解上说需要差分,但是个人感觉和差分关系下不大,无非是处理一下开关状态不同的边界,然后记录罢了。

其实如果时间允许的话我们可以通过bfs求出任意一点与其他点之间变成统一状态的最小操作次数。

但是我们发现所有真正有用的点只有\(2\times k\)个,所以只要bfs这几个点求出到其他点的距离就可以了。

然后由于k的数据比较小,我们直接对于k进行状压就好了,暴力枚举每一个边界点然后更新f数组,最后的满状态的就是ans了。

code

#include<bits/stdc++.h>
using namespace std;
const int N=4e4+10,M=18,K=70.,INF=1061109567;
int n,m,cnt,k,dis[M][N],len[K],f[1<<M],tmp[M];
bool s[N];
queue<int > q;
void bfs(int pos,int val)
{
dis[pos][val]=0;
q.push(val);
while(!q.empty())
{
int num=q.front();
q.pop();
for(int i=1;i<=m;i++)
{
if(num-len[i]>=0&&dis[pos][num-len[i]]>dis[pos][num]+1)
{
dis[pos][num-len[i]]=dis[pos][num]+1;
q.push(num-len[i]);
}
if(num+len[i]<=n&&dis[pos][num+len[i]]>dis[pos][num]+1)
{
dis[pos][num+len[i]]=dis[pos][num]+1;
q.push(num+len[i]);
}
}
}
}
int get_first(int state)
{
int sum=0;
while(!(state&(1<<sum)))
sum++;
return sum;
}
int work(int state)
{
if(f[state]!=INF)
return f[state];
if(!state)
return 0;
int pos=get_first(state);
for(int i=pos+2;i<=cnt;i++)
if(state&(1<<(i-1)))
f[state]=min(f[state],work(state^(1<<pos)^(1<<(i-1)))+dis[pos+1][tmp[i]]);
return f[state];
}
int main()
{
scanf("%d%d%d",&n,&k,&m);
memset(dis,0x3f,sizeof(dis));
memset(f,0x3f,sizeof(f));
for(int i=1,x;i<=k;i++)
{
scanf("%d",&x);
s[x]=true;
}
for(int i=1;i<=m;i++)
scanf("%d",&len[i]);
for(int i=0;i<=n;i++)
if(s[i]!=s[i+1])
tmp[++cnt]=i;
for(int i=1;i<=cnt;i++)
bfs(i,tmp[i]);
printf("%d",work((1<<cnt)-1));
return 0;
}

6.26考试总结(NOIP模拟10)[入阵曲·将军令·星空]的更多相关文章

  1. noip模拟10[入阵曲·将军令·星空](luogu)

    对于这次考试来说,总体考得还是不错的 就是有一个小问题,特判一定要判对,要不然和不判一样,甚至错了还会挂掉30分 还有一个就是时间分配问题,总是在前几个题上浪费太多时间,导致最后一个题完全没有时间思考 ...

  2. [考试总结]noip模拟10

    不小心有咕掉了一段时间 这次考试咕掉的分数也是太多了 然后就是这次暴力完全没有打满 遗憾啊遗憾 T1 入阵曲 前面的题目背景故意引导我们去往矩阵快速幂的方向去想 然而半毛钱关系没有 其实就是维护前缀和 ...

  3. 2021.6.29考试总结[NOIP模拟10]

    T1 入阵曲 二位前缀和暴力n4可以拿60. 观察到维护前缀和时模k意义下余数一样的前缀和相减后一定被k整除,前缀和维护模数,n2枚举行数,n枚举列, 开一个桶记录模数出现个数,每枚举到该模数就加上它 ...

  4. 2021.9.26考试总结[NOIP模拟62]

    T1 set 从\(0\)到\(n\)前缀余数有\(n+1\)个,但只有\(n\)种取值,找到一样的两个输出区间即可. \(code:\) T1 #include<bits/stdc++.h&g ...

  5. 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]

    6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...

  6. 5.23考试总结(NOIP模拟2)

    5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...

  7. 5.22考试总结(NOIP模拟1)

    5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...

  8. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  9. [考试总结]noip模拟23

    因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...

  10. 2021.8.13考试总结[NOIP模拟38]

    T1 a 入阵曲.枚举矩形上下界,之后从左到右扫一遍.用树状数组维护前缀和加特判可以$A$,更保险要脸的做法是双指针扫,因为前缀和单调不减. $code:$ 1 #include<bits/st ...

随机推荐

  1. python实现:有一个列表为num_list,找到一个具有最大和的连续子列表,返回其最大和。

    # 有一个列表为num_list,找到一个具有最大和的连续子列表,返回其最大和.# 示例:# 输入: [-3,1,-1,6,-1,2,4,-5,4]# 输出: 11# 解释: 连续子数组 [6,-1, ...

  2. Python 生成带Logo的圆角带边框二维码

    Python 生成二维码方式就不累述了,不会的自己百度吧 但python生成的二维码太难看了,要么没有logo,要么logo直接贴进去的,难看死了,有的也处理了一下,但没有圆角,也难看: 以下:是不是 ...

  3. 搜索NLP行业模型和轻量化客户定制

    ​简介:开放搜索NLP行业模型和轻量化客户定制方案,解决减少客户标注成本.完全无标注或少量简单标注的等问题,让搜索领域扩展更易用. 特邀嘉宾: 徐光伟(昆卡)--阿里巴巴算法专家 搜索NLP算法 搜索 ...

  4. 一文了解EPaxos核心协议流程

    简介: EPaxos(Egalitarian Paxos)作为工业界备受瞩目的下一代分布式一致性算法,具有广阔的应用前景.但纵观业内,至今仍未出现一个EPaxos的工程实现,甚至都没看到一篇能把EPa ...

  5. 重磅发布|新一代云原生数据仓库AnalyticDB「SQL智能诊断」功能详解

    ​简介: AnalyticDB For MySQL为用户提供了高效.实时.功能丰富并且智能化的「SQL智能诊断」和「SQL智能调优」功能,提供用户SQL性能调优的思路.方向和具体的方法,降低用户使用成 ...

  6. Python内置数据类型性能分析

    timeit模块 timeit模块可以用来测试一小段Python代码的执行速度. class timeit.Timer(stmt='pass', setup='pass', timer=<tim ...

  7. [FAQ] jsoneditor 如何切换 mode 或者选择 modes

    1. 用于切换编辑器模式:text.tree.code JSONEditor.setMode(mode) 2. 让 mode 变成可以选择的: const options = { modes: ['t ...

  8. [FAQ] 阿里云一口价域名购买之后在哪里看

    进入控制台,产品和服务中找到"域名",进去后在左侧菜单有 "已买到的域名". 如图: Link:https://www.cnblogs.com/farwish/ ...

  9. Part-DB 配置流程

    介绍 Part-DB是一个开源的器件管理工具,博主用于管理个人的电子器材,最近捣鼓了一下这个工具,由于手头还有一块闲置的赛昉·星光2的开发板,所以我打算一起拿来捣鼓一下,如果不成功,就用树莓派(生气) ...

  10. 5.k8s Service四层负载:服务端口暴露

    题目一:暴露服务service 设置配置环境: [candidate@node-1] $ kubectl config use-context k8s Task 请重新配置现有的 deployment ...