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题解的更多相关文章

  1. NOIP2017 题解

    QAQ--由于没报上名并没能亲自去,自己切一切题聊以慰藉吧-- 可能等到省选的时候我就没有能力再不看题解自己切省选题了--辣鸡HZ毁我青春 D1T1 小凯的疑惑 地球人都会做,懒得写题解了-- D1T ...

  2. [NOIP补坑计划]NOIP2017 题解&做题心得

    终于做完了…… 场上预计得分:?(省一分数线:295) 由于看过部分题解所以没有预计得分qwq 题解: D1T1 小凯的疑惑 题面 震惊!一道小学奥数题竟难倒无数高中考生! 欢迎大家以各种姿势*和谐* ...

  3. NOIP2017 题解(给自己看的) --有坑要填

    目录 D1T1精妙证明: D1T3 D2T2 几道水题就不写了.... D1T1精妙证明: 把ax+by = z 的z按照模a剩余系分类 由于\((a,b)=1\)所以对于每个\(k\in[0, a) ...

  4. 【NOIP题解】NOIP2017 TG D2T3 列队

    列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...

  5. NOIP2017 列队 题解报告【56行线段树】

    题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数 ...

  6. noip2017爆炸记——题解&总结&反省(普及组+提高组)

    相关链接: noip2018总结 noip2017是我见过的有史以来最坑爹的一场考试了. 今年北京市考点有一个是我们学校,我还恰好被分到了自己学校(还是自己天天上课的那个教室),于是我同时报了普及提高 ...

  7. 题解[NOIP2017] 列队

    题解[NOIP2017] 列队 题面 解析 看到这题时感觉这个编号很难维护啊? 后来看了lzf大佬的题解才会.. 首先,考虑一个稍微暴力的做法, 维护每一行的前\(m-1\)个人和最后一列的\(n\) ...

  8. 【题解】NOIP2017 提高组 简要题解

    [题解]NOIP2017 提高组 简要题解 小凯的疑惑(数论) 不讲 时间复杂度 大力模拟 奶酪 并查集模板题 宝藏 最优解一定存在一种构造方法是按照深度一步步生成所有的联通性. 枚举一个根,随后设\ ...

  9. 【题解】NOIP2017逛公园(DP)

    [题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n​节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...

随机推荐

  1. css行内省略号、垂直居中

    应用场景分析: 一.当你的文字限定行数,超出部分的文字用省略号显示. (有两个使用场景:1.单行 2.多行) // 单行 overflow: hidden; text-overflow:ellipsi ...

  2. vue中的适配:px2rem

    这应该是vue项目在适配移动端时候,最简单的方法之一下面是基本步骤(使用cnpm)1.下载并引入lib-flexible cnpm install --save lib-flexible 在main. ...

  3. Flutter之Container详解

    1 基本内容1.1 继续关系Object > Diagnosticable > DiagnosticableTree > Widget > StatelessWidget &g ...

  4. Python 命令行工具 argparse 模块使用详解

    先来介绍一把最基本的用法 import argparse parser = argparse.ArgumentParser() parser.parse_args() 在执行 parse_args() ...

  5. 老男孩 python学习自修第二十二天【文件上传与下载】

    1.使用socket实现文件上传 server.py #!/usr/bin/env python # _*_ coding:UTF-8 _*_ import os import SocketServe ...

  6. 原子变量与CAS算法(二)

    一.锁机制存在的问题 (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2)一个线程持有锁会导致其它所有需要此锁的线程挂起. (3)如果一个优先级高的线程等待一个 ...

  7. matlab中randn(‘state’)

    matlab中randn(‘state’)转载:http://www.cnblogs.com/rong86/p/3572284.html randn('state') 随机数都是由RandStream ...

  8. React 学习(四) ---- 生命周期函数

    现在我们能修改状态,页面可以进行交互了,但是还有一种状态改变没有解决,那就是倒计时效果,时间一直在变化,组件状态也一直在改变,但我们什么都没有做,如果要实现这样的效果,需要怎么处理? 我们都知道,改变 ...

  9. robotframework编写用例

    ** Test Cases *** Test With Settings [Documentation] Another dummy test # 用于指定测试用例文档 [Tags] dummy ow ...

  10. 如何简单实现接口自动化测试(基于 python) 原博主地址https://blog.csdn.net/gitchat/article/details/77849725

    如何简单实现接口自动化测试(基于 python) 2017年09月05日 11:52:25 阅读数:9904 GitChat 作者:饿了么技术社区 原文:如何简单实现接口自动化测试(基于 python ...