NOIP2017题解
T1小凯的疑惑
小凯手中有两种面值的金币,两种面值均为正整数且彼此互素。每种金币小凯都有 无数个。在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的。现在小 凯想知道在无法准确支付的物品中,最贵的价值是多少金币?注意:输入数据保证存在 小凯无法准确支付的商品。
Solution
2017数论题,感觉是历史以来最难的一道。
对于ax+by=c(a>=0,b>=0)当方程无解是,必定为x<0&&y>0且下一组解x>0&&y<0那x为-1,y为a-1,那c就是a*b-a-b。
Code
#include<iostream>
#include<algorithm>
using namespace std;
long long a,b;
int main()
{
cin>>a>>b;
cout<<a*b-a-b;
}
T2时间复杂度
题面太长不粘了
模拟题,注意细节。。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int t,vis[],tag,tag2,n,ans,num,tot,s[],st[],top,maxx=,yy,zz;
char c,cc[],x,y[],z[];
int main()
{
cin>>t;
while(t--)
{
memset(vis,,sizeof(vis));
scanf("%d",&n);
tag=tag2=tot=num=ans=top=;
cin>>cc;
int p=strlen(cc);
if(cc[]=='n')
for(int j=;j<=p;++j)
if(cc[j]>=''&&cc[j]<='') num=num*+cc[j]-'';
else break;
for(int i=;i<=n;++i)
{
cin>>c;
if(c=='F')
{
cin>>x>>y>>z;
yy=zz=;
if(vis[x])tag=;
vis[x]=;
s[++top]=x;
if(y[]!='n')
{
int o=strlen(y);
for(int k=;k<o;++k)
yy=yy*+y[k]-'';
}
else yy=maxx;
if(z[]!='n')
{
int o=strlen(z);
for(int k=;k<o;++k)
zz=zz*+z[k]-'';
}
else zz=maxx;
if(yy<maxx&&zz==maxx)
{
st[top]=;
tot++;
}
else
if(yy>zz)
{
st[top]=-;
tag2++;
}
else
{
st[top]=;
}
if(!tag2)ans=max(ans,tot);
}
else
{
if(!top)tag=;
if(st[top]==)tot--;
else if(st[top]==-)tag2--;
vis[s[top]]=;
top--;
}
}
if(top||tag)
{
cout<<"ERR\n";
continue;
}
if(ans==num)cout<<"Yes\n";
else cout<<"No\n";
}
return ;
}
T3逛公园
T4奶酪
现有一块大奶酪,它的高度为 hh,它的长度和宽度我们可以认为是无限大的,奶酪 中间有许多 半径相同 的球形空洞。我们可以在这块奶酪中建立空间坐标系,在坐标系中, 奶酪的下表面为z = 0z=0,奶酪的上表面为z = hz=h。
现在,奶酪的下表面有一只小老鼠 Jerry,它知道奶酪中所有空洞的球心所在的坐 标。如果两个空洞相切或是相交,则 Jerry 可以从其中一个空洞跑到另一个空洞,特别 地,如果一个空洞与下表面相切或是相交,Jerry 则可以从奶酪下表面跑进空洞;如果 一个空洞与上表面相切或是相交,Jerry 则可以从空洞跑到奶酪上表面。
位于奶酪下表面的 Jerry 想知道,在 不破坏奶酪 的情况下,能否利用已有的空洞跑 到奶酪的上表面去?
Solution
水题 ,可以把上界和下界都看成一个点,n^2并查集搞一下就可以了。
听说这题爆longlong,反正我开double直接开根,精度没什么问题。
Code
#include<iostream>
#include<cstdio>
#include<cmath>
#define N 1012
using namespace std;
int n,t,f[N];
double h,r;
struct ssd{
double x,y,z;
}a[N];
double calc(int i,int j){
return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)+(a[i].z-a[j].z)*(a[i].z-a[j].z));
}
int find(int x){return f[x]=f[x]==x?x:find(f[x]);}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%lf%lf",&n,&h,&r);
for(int i=;i<=n+;++i)f[i]=i;
for(int i=;i<=n;++i){
scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z);
for(int j=;j<i;++j)
if(calc(i,j)<=r*){
int xx=find(i),yy=find(j);
if(xx!=yy)f[xx]=yy;
}
if(a[i].z-r<=){
int xx=find(i),yy=find();
if(xx!=yy)f[xx]=yy;
}
if(a[i].z+r>=h){
int xx=find(i),yy=find(n+);
if(xx!=yy)f[xx]=yy;
}
}
if(find()==find(n+))printf("Yes\n");
else printf("No\n");
}
return ;
}
T5宝藏
如果我们设dp[s]表示当前选择集合为s时的最小代价,这个状态是有问题的,说不好听点它压根就是错的,因为它压根就没有考虑每个节点的深度。
我们可以这么考虑问题,我们以深度作为阶段,每次从当前选择集合中扩展一些点作为第i层。
这时我们就可以设计状态了,令dp[i][s]表示当前深度做到了i,当前选择集合为s时的最优方案。
转移时可以枚举扩展出哪些点,然后直接转移。
这样的复杂度是3^n*n^2。
但这样太慢,可以利用lowbit等技巧优化常数
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 13
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
int dp[N][<<N],n,m,x,y,l,e[N][N],ji[<<N],f[<<N],b[N],tag[N],be[<<N],ans;
inline int rd(){
int x=;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c)){
x=(x<<)+(x<<)+(c^);c=getchar();
}
return x;
}
int main(){
n=rd();m=rd();
memset(e,0x3f,sizeof(e));
for(int i=;i<=m;++i){
x=rd();y=rd();l=rd();
e[x][y]=e[y][x]=min(e[x][y],l);
}
memset(dp,0x3f,sizeof(dp));
for(int i=;i<n;++i)ji[<<i]=i,dp[][<<i]=;ans=inf;
ans=min(ans,dp[][(<<n)-]);
for(int i=;i<=n;++i)
for(int s=;s<(<<n);++s){
int top=;
memset(b,0x3f,sizeof(b));
for(int j=;j<=n;++j)if(!(s&(<<j-))){
tag[top]=<<j-;
for(int S=s;S;S-=(S&-S))if(e[j][ji[S&-S]+]!=inf)b[top]=min(b[top],e[j][ji[S&-S]+]*i);
top++;
}
for(int j=;j<(<<top);++j){
f[j]=f[j-(j&-j)]+b[ji[j&-j]];
if(f[j]>=inf)f[j]=inf;
be[j]=be[j-(j&-j)]|tag[ji[j&-j]];
dp[i][s|be[j]]=min(dp[i][s|be[j]],dp[i-][s]+f[j]);
}
ans=min(ans,dp[i][(<<n)-]);
}
printf("%d",ans);
return ;
}
T6列队
Solution
观察到最后一列很特殊,考虑分开维护。
对于每行的前m-1个点开线段树,里面记个size有表示这个位置没人。
那么整体向做移动怎么维护?
其实不用管它,毕竟对于前m-1列只会从后面插入。
那么对于一颗线段树,我们的操作只有从后面插入一个节点,从集合删去一个节点和查找第K个元素。
在最后一列开线段树,操作时分类讨论一下。
注意:n和m不要弄反,初始化size要为m-1不是m!!!
Code
#include<iostream>
#include<cstdio>
#define N 300002
using namespace std;
typedef long long ll;
int size[N],T[N],tot,q;
long long x,y,n,m;
struct node{ll first;bool second;};
struct seg{ll num;int l,r,sum;}tr[N*];
node find(int &cnt,int l,int r,int k){
if(!cnt)cnt=++tot;tr[cnt].sum++;
if(l==r){
if(tr[cnt].num)return node{tr[cnt].num,};
else return node{l,};
}
int mid=(l+r)>>,num=mid-l+-tr[tr[cnt].l].sum;
if(num>=k)return find(tr[cnt].l,l,mid,k);
else return find(tr[cnt].r,mid+,r,k-num);
}
void add(int &cnt,int l,int r,int x,ll y){
if(!cnt)cnt=++tot;
if(l==r){tr[cnt].num=y;return;}
int mid=(l+r)>>;
if(mid>=x)add(tr[cnt].l,l,mid,x,y);
else add(tr[cnt].r,mid+,r,x,y);
}
inline int rd(){
int x=;char c=getchar();while(!isdigit(c))c=getchar();
while(isdigit(c))x=(x<<)+(x<<)+(c^),c=getchar();return x;
}
int main(){
n=rd();m=rd();q=rd();
for(int i=;i<=n;++i)size[i]=m-;//care
size[n+]=n;
for(int i=;i<=q;++i){
x=rd();y=rd();
if(y==m){
node tmp=find(T[n+],,n+q,x);
ll num=tmp.first;
if(tmp.second)num=num*m;
printf("%lld\n",num);
add(T[n+],,n+q,++size[n+],num);
}
else{
node tmp=find(T[x],,m+q,y);
ll num=tmp.first;
if(tmp.second)num=num+(x-)*m;
printf("%lld\n",num);
tmp=find(T[n+],,n+q,x);
ll num2=tmp.first;
if(tmp.second)num2=num2*m;
add(T[x],,m+q,++size[x],num2);
add(T[n+],,n+q,++size[n+],num);
}
}
return ;
}
NOIP2017题解的更多相关文章
- NOIP2017 题解
QAQ--由于没报上名并没能亲自去,自己切一切题聊以慰藉吧-- 可能等到省选的时候我就没有能力再不看题解自己切省选题了--辣鸡HZ毁我青春 D1T1 小凯的疑惑 地球人都会做,懒得写题解了-- D1T ...
- [NOIP补坑计划]NOIP2017 题解&做题心得
终于做完了…… 场上预计得分:?(省一分数线:295) 由于看过部分题解所以没有预计得分qwq 题解: D1T1 小凯的疑惑 题面 震惊!一道小学奥数题竟难倒无数高中考生! 欢迎大家以各种姿势*和谐* ...
- NOIP2017 题解(给自己看的) --有坑要填
目录 D1T1精妙证明: D1T3 D2T2 几道水题就不写了.... D1T1精妙证明: 把ax+by = z 的z按照模a剩余系分类 由于\((a,b)=1\)所以对于每个\(k\in[0, a) ...
- 【NOIP题解】NOIP2017 TG D2T3 列队
列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...
- NOIP2017 列队 题解报告【56行线段树】
题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数 ...
- noip2017爆炸记——题解&总结&反省(普及组+提高组)
相关链接: noip2018总结 noip2017是我见过的有史以来最坑爹的一场考试了. 今年北京市考点有一个是我们学校,我还恰好被分到了自己学校(还是自己天天上课的那个教室),于是我同时报了普及提高 ...
- 题解[NOIP2017] 列队
题解[NOIP2017] 列队 题面 解析 看到这题时感觉这个编号很难维护啊? 后来看了lzf大佬的题解才会.. 首先,考虑一个稍微暴力的做法, 维护每一行的前\(m-1\)个人和最后一列的\(n\) ...
- 【题解】NOIP2017 提高组 简要题解
[题解]NOIP2017 提高组 简要题解 小凯的疑惑(数论) 不讲 时间复杂度 大力模拟 奶酪 并查集模板题 宝藏 最优解一定存在一种构造方法是按照深度一步步生成所有的联通性. 枚举一个根,随后设\ ...
- 【题解】NOIP2017逛公园(DP)
[题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...
随机推荐
- 1170 - BLOB/TEXT column 'CustomerName' used in key specification without a key length
[DTF] Data Transfer 企管宝_2_CRM start[DTF] Getting tables[DTF] Analyzing table: `CustomerInfo`[DTF] Ge ...
- MySQL 日期类型函数及使用
1 MySQL 数据库中有五种与日期时间有关的数据类型,各种日期数据类型所占空间如下图所示: 2 datetime 与 date datetime 占用8字节,是占用空间最多的一种日期格式.它显示日期 ...
- [转帖]K8H3D 病毒 腾讯御剑的解析
https://weibo.com/ttarticle/p/show?id=2309404344350225132710 永恒之蓝下载器木马又双叒叕升级了新的攻击方式 背景 腾讯安全御见威胁情报中 ...
- picker-view 组件 的value失效问题
首先检查是不是漏了绑定关系 组件内 组件引用 如过还不行就用下面的方法,顺序问题 在给暂时列表赋值之后再对value赋值
- IntelliJ IDEA详情
详情请参考http://www.phperz.com/article/15/0923/159043.html
- linux 依赖解决办法
在安装软件过程中如果出现依赖不满足,有两种情况: 1:你系统里面没有安装依赖软件,[但是你的软件源里面有这个软件,你只是没有安装], 这种情况很简单,通过 sudo apt-get install - ...
- Python学习之路——Day06 元组
一.元组 t1 = (1, 2) t2 = tuple((1, 2)) t3 = (1, ) # 索引 | 切片 | 长度 # .count(obj) | .index(obj, bIndex, eI ...
- js写插件教程入门
原文地址:https://github.com/lianxiaozhuang/blog 转载请注明出处 1. 点击add可以添加个自input的内容到div里并实现变颜色 <div id=& ...
- Maven问题:Failure to transfer org.apache.maven
Maven报错:Failure to transfer org.apache.maven 在创建Maven项目时,经常会在pom.xml的第一行处报错,提示信息如下: Failure to trans ...
- 学习 Spring (十二) AOP 基本概念及特点
Spring入门篇 学习笔记 AOP: Aspect Oriented Programming, 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 主要功能是:日志记录.性能统计.安全控 ...