首页 > 其他 > 详细

NOIp2014题解

时间:2019-10-28 01:23:48      阅读:109      评论:0      收藏:0      [点我收藏+]

题目链接:https://loj.ac/problems/search?keyword=NOIP2014

D1T1

暴力

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
const int p[][5]={{0,-1,1,1,-1},
                  {1,0,-1,1,-1},
                  {-1,1,0,-1,1},
                  {-1,-1,1,0,1},
                  {1,1,-1,-1,0}};
int n,n1,n2,a[10100],b[10100];

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

int main()
{
    n=read();n1=read();n2=read();
    rep(i,0,n1-1) a[i]=read();
    rep(i,0,n2-1) b[i]=read();
    int ans1=0,ans2=0;
    rep(i,0,n-1)
    {
        int na=a[i%n1],nb=b[i%n2];
        if (p[na][nb]==1) ans1++;
        else if (p[na][nb]) ans2++;
    }
    printf("%d %d",ans1,ans2);
    return 0;
}

D1T2

暴力

dfs这棵树的时候统计以当前节点为中间节点的点对的答案

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 10007
#define eps 1e-8
struct node{int to,nxt;}sq[400400];
int all=0,head[200200];
int n,a[200200];
ll ans=0,maxans=0;

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

void add(int u,int v)
{
    all++;sq[all].to=v;sq[all].nxt=head[u];head[u]=all;
}

void dfs(int u,int fu)
{
    int sum=a[fu];
    int mx1=a[fu],mx2=0;
    for (int i=head[u];i;i=sq[i].nxt)
    {
        int v=sq[i].to;
        if (v==fu) continue;
        dfs(v,u);
        ans=(ans+sum*a[v]%maxd)%maxd;
        sum=(sum+a[v])%maxd;
        if (a[v]>mx1) {mx2=mx1;mx1=a[v];}
        else if (a[v]>mx2) mx2=a[v];
    }
    maxans=max(maxans,1ll*mx1*mx2);
}

int main()
{
    n=read();
    rep(i,1,n-1)
    {
        int u=read(),v=read();
        add(u,v);add(v,u);
    }
    rep(i,1,n) a[i]=read();
    dfs(1,0);
    ans=ans*2%maxd;
    printf("%lld %lld",maxans,ans);
    return 0;
}

D1T3

\(f[i][j]\)表示在\((i,j)\)的时候所需要的最小点击数,那么首先可以用类似背包的方式处理\(x,y\)。接下来还有两个小细节:

(1)对于那些跑出了上边界的情况,我们可以将第二维开大一些,之后把那些超出去的部分全部记在\(f[i][m]\),根据定义这显然是可行的

(2)对于水管直接赋为\(inf\),防止下一次转移被使用

之后就比较简单了

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
int n,m,k,u[100100],d[10010],x[10010],y[10010],dp[10010][2010];
int vis[10010];

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

int main()
{
    n=read();m=read();k=read();
    rep(i,1,n) 
    {
        x[i]=read();y[i]=read();
        d[i]=1;u[i]=m;
    }
    d[0]=1;u[0]=m;
    rep(i,1,k)
    {
        int pos=read();
        d[pos]=read()+1;u[pos]=read()-1;vis[pos]=1;
    }
    memset(dp,0x3f,sizeof(dp));
    rep(i,1,m) 
        if ((i>=d[0]) && (i<=u[0])) dp[0][i]=0;
    rep(i,1,n)
    {
        rep(j,x[i]+1,m+x[i])
        {
            dp[i][j]=min(dp[i-1][j-x[i]]+1,dp[i][j-x[i]]+1);
            if (j>m) dp[i][m]=min(dp[i][m],dp[i][j]);
        }
        rep(j,1,m-y[i])
            dp[i][j]=min(dp[i][j],dp[i-1][j+y[i]]);
        rep(j,1,d[i]-1) dp[i][j]=maxd;
        rep(j,u[i]+1,m) dp[i][j]=maxd;
    }
    int ans=maxd;
    rep(i,1,m) ans=min(ans,dp[n][i]);
    if (ans<maxd) printf("1\n%d",ans);
    else
    {
        per(i,n-1,0)
        {
            rep(j,1,m)
            {
                if (dp[i][j]<maxd)
                {
                    int ans=0;
                    rep(k,0,i) ans+=vis[k];
                    printf("0\n%d",ans);
                    return 0;
                }
            }
        }
    }
    return 0;
}

D2T1

暴力

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
int n=0,m=0,k,d,a[310][310];

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

int main()
{
    d=read();k=read();
    rep(i,1,k) 
    {
        int x=read(),y=read();
        n=max(x,n);m=max(y,m);
        a[x][y]=read();
    }
    int ans=0,cnt=0;
    rep(i,0,n) rep(j,0,m)
    {
        int sum=0;
        rep(p,max(0,i-d),min(n,i+d))
            rep(q,max(0,j-d),min(m,j+d))
                sum+=a[p][q];
        if (ans<sum) {ans=sum;cnt=0;}
        if (ans==sum) cnt++;
    }
    printf("%d %d",cnt,ans);
    return 0;
}

D2T2

第一遍bfs倒着做,找到所有可以用的点

第二遍bfs正着做,求答案

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
struct node{int to,nxt;}sq[200200],sq1[200200];
int all=0,all1=0,head[10010],head1[10010];
int n,m,dis[10010],ok[10010],vis[10010],st,ed;

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

void add(int u,int v)
{
    all++;sq[all].to=v;sq[all].nxt=head[u];head[u]=all;
}

void add1(int u,int v)
{
    all1++;sq1[all1].to=v;sq1[all1].nxt=head1[u];head1[u]=all1;
}

void bfs1()
{
    queue<int> q;
    q.push(ed);vis[ed]=1;
    while (!q.empty())
    {
        int u=q.front();q.pop();
        for (int i=head1[u];i;i=sq1[i].nxt)
        {
            int v=sq1[i].to;
            if (!vis[v])
            {
                vis[v]=1;
                q.push(v);
            }
        }
    }
}

int bfs2()
{
    queue<int> q;
    memset(dis,0x3f,sizeof(dis));
    q.push(st);dis[st]=0;
    while (!q.empty())
    {
        int u=q.front();q.pop();
        for (int i=head[u];i;i=sq[i].nxt)
        {
            int v=sq[i].to;
            if ((ok[v]) && (dis[v]>=maxd))
            {
                dis[v]=dis[u]+1;
                q.push(v);
            }
        }
    }
    if (dis[ed]>=maxd) return -1;
    else return dis[ed];
}

int main()
{
    n=read();m=read();
    rep(i,1,m)
    {
        int u=read(),v=read();
        add(u,v);add1(v,u);
    }
    st=read();ed=read();
    bfs1();
    rep(u,1,n)
    {
        ok[u]=1;
        for (int i=head[u];i;i=sq[i].nxt)
        {
            int v=sq[i].to;
            if (!vis[v]) ok[u]=0;
        }
    }
    int ans=bfs2();
    printf("%d",ans);
    return 0;
}

D2T3

枚举答案,hash判断合法

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
int n,m;
ll a[110];
vector<int> ans;

ll read()
{
    ll x=0;int f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=(x*10+(ch-'0'))%maxd;ch=getchar();}
    return (x*f+maxd)%maxd;
}

int main()
{
    scanf("%d %d",&n,&m);
    rep(i,0,n) a[i]=read();
    //rep(i,0,n) cout << a[i] << " ";cout << endl;
    rep(i,1,m)
    {
        ll powe=1,sum=0;
        rep(j,0,n)
        {
            sum=(sum+powe*a[j])%maxd;
            powe=powe*i%maxd;
        }
        if (!sum) ans.pb(i);
    }
    int len=ans.size();
    printf("%d\n",len);
    rep(i,0,len-1) printf("%d\n",ans[i]);
    return 0;
}

NOIp2014题解

原文:https://www.cnblogs.com/encodetalker/p/11749807.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!