noip 2017 提高组

T1 神奇的幻方 题目传送门 就只是一道模拟题 水水水

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
int map[55][55],x[2507],y[2507],n;
int main()
{
    n=read();
    map[1][(n+1)/2]=1;
    x[1]=1; y[1]=(n+1)/2;
    for(int i=2;i<=n*n;i++){
        int nx=x[i-1],ny=y[i-1];
        if(nx==1&&ny<n) map[n][ny+1]=i,x[i]=n,y[i]=ny+1;
        else if(nx!=1&&ny==n) map[nx-1][1]=i,x[i]=nx-1,y[i]=1;
        else if(nx==1&&ny==n) map[nx+1][ny]=i,x[i]=nx+1,y[i]=ny;
        else if(nx!=1&&ny!=n){
            if(!map[nx-1][ny+1]) map[nx-1][ny+1]=i,x[i]=nx-1,y[i]=ny+1;
            else map[nx+1][ny]=i,x[i]=nx+1,y[i]=ny;
        }
    }
    for(int i=1;i<=n;i++,printf("\n"))
        for(int j=1;j<=n;j++)
            printf("%d ",map[i][j]);
    return 0;
}

T2 信息传递题目传送门

这道题呢 搞一波tarjan缩点 最小的环就是答案了哇 不过一个点自成一环的不能算

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=250007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
int n,ans=M;
int top,st[M],book[M];
int low[M],dfn[M],sum;
int first[M],cnt;
struct node{int to,next;}e[2*M];
void ins(int a,int b){sum++; e[sum].to=b; e[sum].next=first[a]; first[a]=sum;}
void dfs(int x){
    dfn[x]=low[x]=++sum;
    st[++top]=x;
    book[x]=1;
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(!dfn[now]){
            dfs(now);
            low[x]=min(low[x],low[now]);
        }
        if(book[now]) low[x]=min(low[x],dfn[now]);
    }
    if(low[x]==dfn[x]){
        int sum=1;
        book[x]=0;
        while(st[top]!=x){
            int now=st[top--];
            book[now]=0;
            sum++;
        }
        top--;
        if(sum>1) ans=min(ans,sum);
    }
}
int main()
{
    int x;
    n=read();
    for(int i=1;i<=n;i++) x=read(),ins(i,x);
    for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);
    printf("%d\n",ans);
    return 0;
}

T3 斗地主题目传送门

很佩服写这道题的人 我比较懒所以就跳了...23333

T4 跳石头 题目传送门  这就是道简单的二分

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
int s[50007],n,m,v;
int l,r,k,old;
int pd(int w){
    int ans=0,sum=0;
    for(int i=1;i<=n;i++)
    {
        if(s[i]-sum<=w) ans++;
        else    sum=s[i];
    }
    return ans<=m;
}
int main()
{
    v=read(); n=read(); m=read();
    l=0; r=v+1;
    for(int i=1;i<=n;i++) s[i]=read();
    n++; s[n]=v;
    while(l<=r){
        int mid=(l+r)>>1;
        if(pd(mid)) l=mid+1;
        else r=mid-1;
    }
    printf("%d\n",l);
    return 0;
}

T5 子串 题目传送门 这道题就是个DP 自己讲得不好 推荐个博客吧orz

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1507,mod=1000000007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
int n,m,cnt,now,last=1;
char a[M],b[M];
int f[2][M][M],s[2][M][M];
int main()
{
    n=read(); m=read(); cnt=read(); //printf("[%d %d %d]\n",n,m,cnt);
    scanf("%s %s",a+1,b+1); //printf("%s %s",a+1,b+1);
    s[0][0][0]=s[1][0][0]=1;
    for(int i=1;i<=n;i++){
        now^=1; last^=1;
        for(int j=1;j<=m;j++){
            if(a[i]==b[j]) for(int k=1;k<=cnt;k++)
            f[now][j][k]=(f[last][j-1][k]+s[last][j-1][k-1])%mod,s[now][j][k]=(s[last][j][k]+f[now][j][k])%mod;
            else for(int k=1;k<=cnt;k++)
            f[now][j][k]=0,s[now][j][k]=s[last][j][k];
        }
    }
    printf("%d\n",s[n%2][m][cnt]);
    return 0;
}

T6 运输计划 题目传送门

这是道lca加二分 果然自己还是太弱了没写出来 看了波题解才懂的 orzzsn 推荐个博客吧

我感觉吧 sum处理的时候就像是打标记一样所以sum【l【i】】++,sum【r【i】】++,sum【lca【i】-=2; 就是把l【i】到r【i】的路径打一波标记好处理 2333

具体看思诺大爷的题解吧 orz

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=350007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
int l[M],r[M],lca[M],dis[M],deep[M],f[M][25],sum[M],v[M],T[M],vis[M];
int n,m,x,y,w;
int cnt,first[M];
struct node{int to,next,w;}e[2*M];
void ins(int a,int b,int w){cnt++; e[cnt].to=b; e[cnt].w=w; e[cnt].next=first[a]; first[a]=cnt;}
void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
void dfs(int x){
    vis[x]=1;
    for(int i=1;(1<<i)<=deep[x];i++) f[x][i]=f[f[x][i-1]][i-1];
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(!vis[now]){
            deep[now]=deep[x]+1;
            v[now]=e[i].w;
            dis[now]=dis[x]+v[now];
            f[now][0]=x;
            dfs(now);
        }
    }
}
int find(int x,int y){
    if(deep[x]<deep[y]) swap(x,y);
    int d=deep[x]-deep[y];
    for(int i=0;(1<<i)<=d;i++) if((1<<i)&d) x=f[x][i];
    if(x==y) return x;
    for(int i=25;i>=0;i--)
     if((1<<i)<=deep[x]&&f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
void push_sum(int x){
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(now!=f[x][0]) push_sum(now),sum[x]+=sum[now];
    }
}
int check(int mid){
    int cnt=0,cmax=0;
    for(int i=1;i<=n;i++) sum[i]=0;
    for(int i=1;i<=m;i++) if(T[i]>mid){
        cnt++; cmax=max(cmax,T[i]-mid);
        sum[l[i]]++; sum[r[i]]++; sum[lca[i]]-=2;
    }
    push_sum(1);
    for(int i=1;i<=n;i++)
     if(sum[i]==cnt&&v[i]>=cmax) return 1;
    return 0;
}
int main()
{
    n=read(); m=read();
    for(int i=1;i<n;i++) x=read(),y=read(),w=read(),insert(x,y,w);
    dfs(1);
    for(int i=1;i<=m;i++){
        l[i]=read(); r[i]=read();
        lca[i]=find(l[i],r[i]);
        T[i]=dis[l[i]]+dis[r[i]]-2*dis[lca[i]];
    }
    //for(int i=1;i<=m;i++) printf("[%d %d %d %d]\n",l[i],r[i],lca[i],T[i]);
    int L=0,R=0;
    for(int i=1;i<=m;i++) R=max(R,T[i]);
    while(L<=R){
        int mid=(L+R)>>1;
        if(check(mid)) R=mid-1;
        else L=mid+1;
    }
    printf("%d\n",L);
    return 0;
}

时间: 2024-08-03 22:32:52

noip 2017 提高组的相关文章

NOIP 2012 提高组 DAY1 T2 国王游戏

题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果. 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大臣,所获奖赏尽可能的少

NOIP 2014 提高组 题解

NOIP 2014 提高组 题解 No 1. 生活大爆炸版石头剪刀布 http://www.luogu.org/problem/show?pid=1328 这是道大水题,我都在想怎么会有人错了,没算法,直接模拟,别读错题. 1 int wn[5][5]={{2,0,1,1,0}, 2 {1,2,0,1,0}, 3 {0,1,2,0,1}, 4 {0,0,1,2,1}, 5 {1,1,0,0,2}}; 6 7 int n,na,nb; 8 int a[222],b[222]; 9 int s1,s

NOIP 2008提高组第三题题解by rLq

啊啊啊啊啊啊今天已经星期三了吗 那么,来一波题解吧 本题地址http://www.luogu.org/problem/show?pid=1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊

NOIP 2006 提高组 t1 能量项链

题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m*r*n(Mars单位),新产生的珠子的头标

扩展欧几里得模板(洛谷1082 同余方程NOIP 2012 提高组 第二天 第一题)

题目描述 求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 输入输出格式 输入格式: 输入只有一行,包含两个正整数 a, b,用一个空格隔开. 输出格式: 输出只有一行,包含一个正整数 x0,即最小正整数解.输入数据保证一定有解. 输入输出样例 输入样例#1: 3 10 输出样例#1: 7 说明 [数据范围] 对于 40%的数据,2 ≤b≤ 1,000: 对于 60%的数据,2 ≤b≤ 50,000,000: 对于 100%的数据,2 ≤a, b≤ 2,000,000,000

模拟(玩具谜题NOIP 2016 提高组 Day 1 第一题vijos2003)

描述 小南有一套可爱的玩具小人,它们各有不同的职业. 有一天,这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉小南一个谜题:“眼镜藏在我左数第3个玩具小人的右数第1个玩 具小人的左数第2个玩具小人那里.” 小南发现,这个谜题中玩具小人的朝向非常关键,因为朝内和朝外的玩具小人的左右方向是相反的:面朝圈内的玩具小人,它的左边是顺时针方向,右边是逆时针方向:而面向圈外的玩具小人,它的左边是逆时针方向,右边是顺时针方向. 小

NOIP 2002提高组 选数 dfs/暴力

1008 选数 2002年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和.例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为: 3+7+12=22 3+7+19=29 7+12+19=38 3+12+19=34. 现在,要求你计算出和为素

noip 2016 提高组试题看法

前几天写的那个纯属搞笑.(额,好吧,其实这个也不怎么正经) 就先说说day2吧: T1:这个东西应该叫做数论吧. 然而我一看到就照着样例在纸上推了大半天(然而还是没有看出来这东西是个杨辉三角) 然后就想干脆先把n≤25的拿了再说(这个爆不了long long) 然后就硬套用那个组合数公式. 再然后,就只拿了35分. T2:我勒个去. 这个东西应该用堆来优化的吧. 然而并不会堆. 然后就切一个遍历一遍把两端都再加进去(虽然我知道这个时间复杂度估计连20都拿不了). 一个估计是正解的东西: 思考一下

NOIP 2013 提高组 day2 积木大赛 找拐点

积木大赛 描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看成由 n 块宽度为1的积木组成,第??块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 n 块高度为 0 的积木).接下来每次操作,小朋友们可以选择一段连续区间[L,R],然后将第 L 块到第 R 块之间(含第 L 块和第 R 块)所有积木的高度分别增加1. 小 M 是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少.但她不是一个勤于动手的孩