2017.9.17校内noip模拟赛解题报告
预计分数:100+60+60=220
实际分数:100+60+40=200
除了暴力什么都不会的我。。。。。
T1 2017.9.17巧克力棒(chocolate)
巧克力棒(chocolate)
Time Limit:1000ms Memory Limit:64MB
题目描述
LYK 找到了一根巧克力棒,但是这根巧克力棒太长了,LYK 无法一口吞进去。
具体地,这根巧克力棒长为 n,它想将这根巧克力棒折成 n 段长为 1 的巧克力棒,然后
慢慢享用。
它打算每次将一根长为 k 的巧克力棒折成两段长为 a 和 b 的巧克力棒,此时若 a=b,则
LYK 觉得它完成了一件非常困难的事,并会得到 1 点成就感。
LYK 想知道一根长度为 n 的巧克力棒能使它得到最多几点成就感。
输入格式(chocolate.in)
第一行一个数 n。
输出格式(chocolate.out)
一个数表示答案。
输入样例
7
输出样例
4
数据范围
对于 20%的数据 n<=5。
对于 50%的数据 n<=20。
对于 80%的数据 n<=2000。
对于 100%的数据 n<=1000000000。
样例解释
将 7 掰成 3+4, 将 3 掰成 1+2, 将 4 掰成 2+2 获得 1 点成就感, 将剩下的所有 2 掰成 1+1
获得 3 点成就感。总共 4 点成就感。
这道题可能是这次考试中我唯一一道推了推结论的题,
对于一个数n,能获得多少成就感我们不知道,
但是我们知道 1+1 = 2一定是n=2的最优情况
那么n=4的时候的最优情况就是(2*1+1)
推广到一般情况,
对于一个n,对他进行二进制拆分,可以证明这样就是最优解。
那么具体怎么拆分呢??
打个表就好啦
时间复杂度O(31)
233333
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- using namespace std;
- const int MAXN=;
- inline void read(long long int &n)
- {
- char c=getchar();n=;bool flag=;
- while(c<''||c>'') c=='-'?flag=,c=getchar():c=getchar();
- while(c>=''&&c<='') n=n*+c-,c=getchar();n=flag==?-n:n;
- }
- long long int pow2[]=
- {
- ,
- ,,,,,
- ,,,,,
- ,,,,,
- ,,,,,
- ,,,,,
- ,,,,
- ,};
- int main()
- {
- //freopen("chocolate.in","r",stdin);
- //freopen("chocolate.out","w",stdout);
- long long n;
- cin>>n;
- long long ans=;
- for(int i=;i>=;i--)
- {
- if(n>=(pow2[i]+))
- {
- n=n-(pow2[i]+);
- ans+=pow2[i];
- }
- }
- printf("%lld",ans);
- return ;
- }
T2 2017.9.17LYK 快跑!(run)
题目描述
LYK 陷进了一个迷宫! 这个迷宫是网格图形状的。 LYK 一开始在(1,1)位置, 出口在(n,m)。
而且这个迷宫里有很多怪兽,若第 a 行第 b 列有一个怪兽,且此时 LYK 处于第 c 行 d 列,此
时这个怪兽对它的威胁程度为|a-c|+|b-d|。 LYK 想找到一条路径,使得它能从(1,1)到达(n,m),且在途中对它威胁程度最小的怪兽的
威胁程度尽可能大。
当然若起点或者终点处有怪兽时,无论路径长什么样,威胁程度最小的怪兽始终=0。
输入输出格式
输入格式:
第一行两个数 n,m。
接下来 n 行,每行 m 个数,如果该数为 0,则表示该位置没有怪兽,否则存在怪兽。
数据保证至少存在一个怪兽。
输入格式(run.out)
一个数表示答案。
输出格式:
输入输出样例
- 3 4
- 0 1 1 0
- 0 0 0 0
- 1 1 1 0
- 1
说明
对于 20%的数据 n=1。
对于 40%的数据 n<=2。
对于 60%的数据 n,m<=10。
对于 80%的数据 n,m<=100。
对于 90%的数据 n,m<=1000。
对于另外 10%的数据 n,m<=1000 且怪兽数量<=100。
一开始的思路是把每个点都拆开跑深搜,
于是乎n^4的做法就诞生了。
然后就开始破罐子破摔了,
反正预处理都n^4了,搜索也写深搜暴力吧,,,
无脑60分,,
正解:
反向考虑,对于一个有怪兽的点(i,j),对他周围的点遍历,
这样的预处理就降成了N^2.
然后爆搜就好了
- nclude<cstdio>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- #include<cstdlib>
- using namespace std;
- const int MAXN=;
- const int INF=0x7ffff;
- inline void read(int &n)
- {
- char c=getchar();n=;bool flag=;
- while(c<''||c>'') c=='-'?flag=,c=getchar():c=getchar();
- while(c>=''&&c<='') n=n*+c-,c=getchar();n=flag==?-n:n;
- }
- int map[MAXN][MAXN];
- int a[MAXN][MAXN];
- int xx[]={-,+,,};
- int yy[]={,,-,+};
- int n,m;
- int flag=;
- int vis[MAXN][MAXN];
- void dfs(int nowx,int nowy,int val)
- {
- if(nowx==n&&nowy==m) { flag=;return ; }
- for(int i=;i<;i++)
- {
- int wx=nowx+xx[i];
- int wy=nowy+yy[i];
- if(map[wx][wy]>=val&&a[wx][wy]==&&wx>&&wy>&&wx<=n&&wy<=m&&vis[wx][wy]==)
- {
- vis[wx][wy]=;
- dfs(wx,wy,val);
- vis[wx][wy]=;
- if(flag==) return ;
- }
- }
- }
- bool check(int val)
- {
- flag=;
- vis[][]=;
- dfs(,,val) ;
- if(flag==) return ;else return ;
- }
- int main()
- {
- //freopen("run.in","r",stdin);
- //freopen("run.out","w",stdout);
- read(n);read(m);
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- read(a[i][j]);
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- map[i][j]=INF;
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- if(a[i][j])
- map[i][j]=INF;
- else
- for(int k=;k<=n;k++)
- for(int l=;l<=m;l++)
- if(a[k][l])
- map[i][j]=min(map[i][j],abs(k-i)+abs(l-j));
- int l=,r=(n*m);
- int ans=;
- while(l<=r)
- {
- int mid=(l+r)>>;
- if(check(mid)) l=mid+,ans=mid;
- else r=mid-;
- }
- printf("%d",ans);
- return ;
- }
60分暴力
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- #include<cstdlib>
- #include<queue>
- using namespace std;
- const int MAXN=;
- const int INF=0x7ffff;
- inline void read(int &n)
- {
- char c=getchar();n=;bool flag=;
- while(c<''||c>'') c=='-'?flag=,c=getchar():c=getchar();
- while(c>=''&&c<='') n=n*+c-,c=getchar();n=flag==?-n:n;
- }
- int xx[]={-,+,,};
- int yy[]={,,-,+};
- int n,m;
- int a[MAXN][MAXN];
- struct POINT
- {
- int x,y;
- }point[MAXN*MAXN],p;
- queue<POINT>q;
- int vis[MAXN][MAXN];
- int dis[MAXN][MAXN];
- bool check(int val)
- {
- queue<POINT>q;
- POINT p;p.x=;p.y=;
- q.push(p);
- memset(vis,,sizeof(vis));
- while(q.size()!=)
- {
- POINT p=q.front();
- if(p.x==n&&p.y==m) return ;
- q.pop();
- for(int i=;i<;i++)
- {
- POINT nxt;
- nxt.x=p.x+xx[i];
- nxt.y=p.y+yy[i];
- if(nxt.x>&&nxt.y>&&nxt.x<=n&&nxt.y<=m&&vis[nxt.x][nxt.y]==&&dis[nxt.x][nxt.y]>=val&&dis[nxt.x][nxt.y]!=INF)
- {
- vis[nxt.x][nxt.y]=;
- q.push(nxt);
- }
- }
- }
- return ;
- }
- int main()
- {
- read(n);read(m);
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- dis[i][j]=INF;
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- {
- read(a[i][j]);
- if(a[i][j])
- {
- dis[i][j]=;
- p.x=i,p.y=j,q.push(p);
- }
- }
- while(q.size()!=)
- {
- POINT p=q.front();
- q.pop();
- for(int i=;i<;i++)
- {
- POINT nxt;
- nxt.x=p.x+xx[i];
- nxt.y=p.y+yy[i];
- if(vis[nxt.x][nxt.y]==&&nxt.x>&&nxt.y>&&nxt.x<=n&&nxt.y<=m)
- {
- vis[nxt.x][nxt.y]=;
- dis[nxt.x][nxt.y]=min(dis[nxt.x][nxt.y],dis[p.x][p.y]+);
- q.push(nxt);
- }
- }
- }
- int l=,r=(n*m);
- int ans=;
- while(l<=r)
- {
- int mid=(l+r)>>;
- if(check(mid)) l=mid+,ans=mid;
- else r=mid-;
- }
- printf("%d",ans);
- return ;
- }
100分AC
T3 2017.9.17仙人掌(cactus)
题目描述
LYK 在冲刺清华集训(THUSC) !于是它开始研究仙人掌,它想来和你一起分享它最近
研究的结果。
如果在一个无向连通图中任意一条边至多属于一个简单环 (简单环的定义为每个点至多
经过一次) ,且不存在自环,我们称这个图为仙人掌。
LYK 觉得仙人掌还是太简单了,于是它定义了属于自己的仙人掌。
定义一张图为美妙的仙人掌, 当且仅当这张图是一个仙人掌且对于任意两个不同的点 i,j,
存在一条从 i 出发到 j 的路径,且经过的点的个数为|j-i|+1 个。 给定一张 n 个点 m 条边且没有自环的图,LYK 想知道美妙的仙人掌最多有多少条边。
数据保证整张图至少存在一个美妙的仙人掌。
输入输出格式
输入格式:
第一行两个数 n,m 表示这张图的点数和边数。
接下来 m 行,每行两个数 u,v 表示存在一条连接 u,v 的无向边。
输出格式:
一个数表示答案
输入输出样例
- 4 6
- 1 2
- 1 3
- 1 4
- 2 3
- 2 4
- 3 4
- 4
- 样例解释
- 选择边 1-2,1-3,2-3,3-4,能组成美妙的仙人掌,且不存在其它美妙仙人掌有超过 4 条
- 边。
说明
对于 20%的数据 n<=3。
对于 40%的数据 n<=5。
对于 60%的数据 n<=8。
对于 80%的数据 n<=1000。
对于 100%的数据 n<=100000 且 m<=min(200000,n*(n-1)/2)。
读题都读的我一脸蒙蔽
于是直接奔着n<=8的情况去了
直接暴力生成所有的图,
然后暴力判断可行不可行。
本来以为能得60分,结果只得了40分。。。
正解:
据某位玄学的大佬说。
i和i+1一定要选(贪心)
而且一定要选满n个点(贪心)
然后跑一边线段覆盖就可以A了(玄学)
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- #include<cstdlib>
- #include<iostream>
- using namespace std;
- const int MAXN=;
- const int INF=0x7ffff;
- inline void read(int &n)
- {
- char c=getchar();n=;bool flag=;
- while(c<''||c>'') c=='-'?flag=,c=getchar():c=getchar();
- while(c>=''&&c<='') n=n*+c-,c=getchar();n=flag==?-n:n;
- }
- struct node
- {
- int u,v,w,nxt;
- }edge[MAXN];
- int head[MAXN];
- int num=;
- inline void add_edge(int x,int y,int z)
- {
- edge[num].u=x;
- edge[num].v=y;
- edge[num].w=z;
- edge[num].nxt=head[x];
- head[x]=num++;
- }
- int n,m;
- int map[MAXN][MAXN];
- int vis[MAXN];// 每个边是否被访问
- int vis2[MAXN];// 每个点是否被访问
- int have[MAXN][MAXN];// 是否满足条件
- int dfs2(int point ,int num)
- {
- for(int i=;i<=n;i++)
- if(abs(point-i)+==num+)
- have[point][i]=;
- for(int i=;i<=n;i++)
- if(map[point][i]&&vis2[i]==)
- {
- vis2[i]=;
- dfs2(i,num+);
- vis2[i]=;
- }
- }
- int nowans;
- int out;
- int vis3[MAXN];
- bool flag3=;
- void pd()
- {
- memset(have,,sizeof(have));
- memset(map,,sizeof(map));
- memset(vis2,,sizeof(vis2));
- memset(vis3,,sizeof(vis3));
- flag3=;
- for(int i=;i<=m;i++)
- {
- if(vis[i])
- {
- map[edge[i].u][edge[i].v]=;
- map[edge[i].v][edge[i].u]=;
- }
- }
- int tot=;
- for(int i=;i<=m;i++)
- if(vis[i]) tot++;
- if(tot>n) return ;
- for(int i=;i<=n;i++)
- {
- vis2[i]=;
- dfs2(i,);
- vis2[i]=;
- }
- for(int i=;i<=n;i++)
- for(int j=;j<=n;j++)
- if(have[i][j]==&&(i!=j)) return ;
- nowans=;
- for(int i=;i<=m;i++)
- if(vis[i])
- nowans++;
- out=max(out,nowans);
- }
- void dfs(int now)
- {
- if(now==m+)
- {
- pd();
- return ;
- }
- vis[now]=;
- dfs(now+);
- vis[now]=;
- dfs(now+);
- }
- int main()
- {
- // freopen("cactus.in","r",stdin);
- //freopen("cactus.out","w",stdout);
- read(n);read(m);
- if(n==)
- {
- printf("");
- return ;
- }
- if(n<=)
- {
- for(int i=;i<=m;i++)
- {
- int x,y;read(x);read(y);
- add_edge(x,y,);
- }
- dfs();
- printf("%d",out);
- }
- else
- {
- printf("%d",rand()%m);
- }
- return ;
- }
40分暴力
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- #include<cstdlib>
- #include<queue>
- using namespace std;
- const int MAXN=;
- const int INF=0x7ffff;
- inline void read(int &n)
- {
- char c=getchar();n=;bool flag=;
- while(c<''||c>'') c=='-'?flag=,c=getchar():c=getchar();
- while(c>=''&&c<='') n=n*+c-,c=getchar();n=flag==?-n:n;
- }
- int n,m;
- struct node
- {
- int bg,ed;
- }point[MAXN];
- int tot=;
- int comp(const node &a ,const node &b)
- {
- return a.ed<b.ed;
- }
- int main()
- {
- read(n);read(m);
- for(int i=;i<=m;i++)
- {
- int x,y;read(x);read(y);
- if(x>y) swap(x,y);
- if(x!=y-) point[++tot].bg=x,point[tot].ed=y;
- }
- sort(point,point+tot+,comp);
- int cur=;
- int ans=;
- for(int i=;i<=tot;i++)
- {
- if(cur<=point[i].bg)
- {
- cur=point[i].ed;
- ans++;
- }
- }
- printf("%d",ans+n-);
- return ;
- }
100分AC
总结:
现在的我相比以前确实稳重了许多,
不会再傻傻的去开一个10000*10000的数组,
也不会再智障的在freopen里多敲一个空格。
但是,因为种种原因,
我很少能想出正解
是因为先天智商太低?
还是因为拿了暴力分之后就沾沾自喜?
亦或是懒得动笔去自喜分析?
这确实是一个严峻的问题,,
那么我前进的方向也就很明确了:
在拿到暴力分的基础上,拼尽全力想正解!
2017.9.17校内noip模拟赛解题报告的更多相关文章
- 2018.10.16 NOIP模拟赛解题报告
心路历程 预计得分:\(100 + 100 + 20 = 220\) 实际得分:\(100 + 100 + 30 = 230\) 辣鸡模拟赛.. T1T2都是一眼题,T3考验卡常数还只有一档暴力分. ...
- 2015-9-13 NOIP模拟赛解题报告(by hzwer)
小奇挖矿 「题目背景」 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞过喵星系的n个星球. 「问题描述」 星球分为2类:资源型和维修型. 1.资源型:含矿物质量a[i ...
- 20161022 NOIP模拟赛 解题报告
好元素 [问题描述] 小A一直认为,如果在一个由N个整数组成的数列{An}中,存在以下情况: Am+An+Ap = Ai (1 <= m, n, p < i <= N , m,n ...
- 9月24日noip模拟赛解题报告
1.校门外的树(tree.c/cpp/pas 128M,1s) Description LSGJ扩建了,于是校门外有了一条长为L的路.路上种了一排的树,每相邻两棵树之间的距离为1,我们可以把马路看成一 ...
- 2018-11-1 NOIP 模拟赛解题报告
T1 Domino 多米诺骨牌 题目大意 给你N个骨牌,上下各有一个数,要使上面一排的和为偶数,同时下面一排的和也为偶数,最多要翻转多少次?如果无法达成那么输出-1. 解法 水题秒切 根据数的奇偶性质 ...
- 2018.10.03 NOIP+ 模拟赛 解题报告
得分: \(30+5+0=35\)(考得真不咋滴) \(T1\):奥义商店(点此看题面) 以为很简单,对着这题想了一个多小时,最后果断打了个暴力交了... ... 看完题解发现其实也不是很难. 对于\ ...
- 10.30 NFLS-NOIP模拟赛 解题报告
总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...
- 20201101gryz模拟赛解题报告
写在前面 2020rp++ 停课的第一场模拟赛 拿上一年的上一年的day1来考的, 结果得分期望220pts,实际135pts,rank3,太菜了 考着考着机房灯突然灭了,当时慌的一批 以为断电代码要 ...
- 2018.10.17NOIP模拟赛解题报告
心路历程 预计得分:\(100 + 100 +100\) 实际得分:\(100 + 100 + 60\) 辣鸡模拟赛.. 5min切掉T1,看了一下T2 T3,感觉T3会被艹爆因为太原了.. 淦了20 ...
随机推荐
- 一片非常有趣的文章 三分钟读懂TT猫分布式、微服务和集群之路
原文http://www.cnblogs.com/smallSevens/p/7501932.html#3782600 三分钟读懂TT猫分布式.微服务和集群之路 针对新手入门的普及,有过大型网站技 ...
- CodeForces 445E DZY Loves Colors
DZY Loves Colors Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces ...
- 在oracle中采用connect by prior来实现递归查询
注明:该文章为引用别人的文章,链接为:http://blog.csdn.net/apicescn/article/details/1510922 , 记录下来只是为了方便查看 原文: connect ...
- Redis加入Centos Linux开机启动
Redis加入Centos Linux开机启动 网上有很多redis在linux下自动启动的例子,实现的方式很多,很多都是参考一个老外流传出来启动的例子,其实直接使用是不行,而且有很多地方有一些语法错 ...
- js面向对象编程:怎样定义常量?
js中有一个keywordconst,但眼下的浏览器似乎还不支持,假设一定要定义一些常量,事实上能够使用闭包,匿名函数实现常量的定义. 比如: var Class = (function() { va ...
- jquery开发之代码风格
1,链式操作风格. (1) 对于同一个对象不超过三个操作的.可直接写成一行.代码例如以下: $("li").show().unbind("click"); (2 ...
- 英语音乐---三、Cry on my shoulder
英语音乐---三.Cry on my shoulder 一.总结 一句话总结:Cry on my shoulder 在我的肩膀上哭泣 1.If the hero never comes to you. ...
- php中命名空间和use
php中命名空间和use 总结 php中的namespace就有点像java中package包的概念 php中的use的概念就是用别人的命名空间中的类 php中的include enquire是引入文 ...
- 4. idea常用快捷键设置(改为eclipse相似)
转自:https://blog.csdn.net/loveer0/article/details/82697877 idea常用快捷键设置(改为eclipse相似) 目录 idea常用快捷键设置改为e ...
- 安卓开发--WebView
package com.zhangxi.test01; import android.app.Activity;import android.app.ProgressDialog;import and ...