NOIP2014 improve group solution to a problem report

D1

T1 wireless network transmitter site

Subject to the effect: find a rectangle, so that maximum coverage of the target point.

Title over the waterDirectly engage in violence in the past, the code is not posted.
But I actually have a place to SB TM, and enter the tone for a long time only to find there is a problem:

scanf("%d%d%d",&x,&y,&t[x][y]);//这是我原来的写法.....

T2 finding your way

Title effect: to give you a directed graph, to find a shortest path from start to finish, and all points on the path pointed edge point and end point communication directly or indirectly.

To satisfy the condition of all the processing points, and then run on topDead\ (spfa \) can be.
Note that we do not go directly to the point and the end point is connected, as this will miss some point (Do not ask how I know).
So we can not use the ending point of a new talk to other points.

\(Code:\)

const int N=2e5+5;
vector<int>G1[N],G2[N];
//G1正图  G2反图
bool T[N],f[N];
int n,m,x,y,s,t,d[N];
queue<int>q;
inline void bfs()
{
    q.push(t);T[t]=f[t]=1;
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(rg int i=0;i<G2[x].size();++i)
        {
            int v=G2[x][i];
            if(!T[v]) T[v]=f[v]=1,q.push(v);
        }
    }
    for(rg int i=1;i<=n;++i)
        if(!T[i])
            for(rg int j=0;j<G2[i].size();++j)
            {
                int v=G2[i][j];
                if(f[v]) f[v]=0;
            }
    while(!q.empty()) q.pop();
    q.push(s);memset(d,0x3f,sizeof d);d[s]=0;
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(rg int i=0;i<G1[x].size();++i)
        {
            int v=G1[x][i];
            if(f[v] && d[v]>d[x]+1)
            {
                d[v]=d[x]+1;
                q.push(v);
            }
        }
    }
}

T3 solving equations

Title effect: seeking a given one yuan \ (n-\) in order equation \ ([1, m] \ ) integer solutions on.

I initially thought it fight high precision, in fact, you can use Horner's method to solve.
This algorithm can monohydric \ (n-\) times polynomial evaluation problem into \ (n-\) th primary arithmetic formula, then ......Look own degree of your mother right
In short, this algorithm allows us \ (O (nm) \) in time to solve the problem. (Can easily process a number of films such as192*****To simplify the operation)

\(Code:\)

#include<cstdio>
#include<vector>
using namespace std;
#define int long long
const int p=19260817;
int n,m,a[105];
vector<int>Ans;
inline int read()//骚气读入
{
    int f=1,x=0;register char c=getchar();
    while(c>'9' || c<'0') {if(c=='-') f=-1;c=getchar();}
    while(c>='0' && c<='9') x=((x<<3)+(x<<1)+(c^'0'))%p,c=getchar();
    return x*f%p;//记得取膜
}
signed main()
{
    n=read(),m=read();
    for(int i=0;i<=n;++i) a[i]=read();
    for(int i=1;i<=m;++i)
    {
        int ans=0;
        for(int j=n;j>=1;--j)
            ans=(ans+a[j])*i%p;
        ans=(ans+a[0])%p;
        if(!ans) Ans.push_back(i);
    }
    printf("%lld\n",(int)Ans.size());
    for(int i=0;i<(int)Ans.size();++i) printf("%lld\n",Ans[i]);
    return 0;
}

D2

T1 The Big Bang version of rock-paper-scissors

Subject to the effect:rock-paper-scissors

Giant water simulation, paste the code on the line ~

\(Code:\)

#include<cstdio>
using namespace std;
const int N=205;
int n,na,nb,a[N],b[N],c[5][5],cnta,cntb;
//0表示“剪刀”,1表示“石头”,2表示“布”,3表示“蜥蜴人”,  4表示“斯波克
int main()
{
    scanf("%d%d%d",&n,&na,&nb);
    for(int i=1;i<=na;++i) scanf("%d",&a[i]);
    for(int i=1;i<=nb;++i) scanf("%d",&b[i]);
    c[1][0]=c[2][1]=c[0][2]=c[0][3]=c[1][3]=c[2][4]=c[3][4]=c[3][2]=c[4][0]=c[4][1]=1;
    for(int i=1;i<=n;++i)
    {
        int A=i%na,B=i%nb;
        if(!A) A=na;
        if(!B) B=nb;
        // printf("%d %d\n",a[A],b[B]);
        cnta+=c[a[A]][b[B]],cntb+=c[b[B]][a[A]];
        // printf("cnt:%d %d\n",cnta,cntb);
    }
    printf("%d %d",cnta,cntb);
    return 0;
}

T2 joint weights

Topic effect: to give you a tree, the right side are \ (1 \) , each point a little right \ (w_i \) ( \ (w_i \ Le 2 \ Times 10 ^ 4 \) ), seeking \ (Max_ { DIS (U, V) = 2} W [U] \ W Times [V] \) , \ (\ sum_ {DIS (U, V) = 2} W [U] \ W Times [V] \) . ( \ (N-\ Le 2 \ ^ 10. 5 Times \) )

Direct \ (O (n ^ 2) \) violence enumeration is certainly not over, in order to some of theClever but uselessTo optimize.

Requirements \ (u, v \) distance is \ (1 \) , but also in the trees, then there must be between them \ (1 \) a transit point. So we can enumerate the points.

But \ (n \) huge range of how efficiently with the new answer it? There is a magic formula:

Set \ (S = \ sum_ {I}. 1 ^ n-a_i = \) , there

\(( (S - a_1) + (S - a_2) + \cdots + (S - a_n) ) \times 2 = (a_1+a_2+ \cdots +a_{n-1}+a_n)^2 - (a_1^2+a_2^2+ \cdots +a_{n-1}^2+a_n^2)\)

Because we added a two-way edge , so for a node \ (the X-\) , between all points connected to it can constitute another joint weights

It represented:

  • Order \ (S \) is the weight of all points connected to it, then the combined weight of any point is capable of forming a \ (S - a_i \)
  • So this point as the combined weights of the formed transit point, for the \ (((S - A_1) + (S - A_2) + \ cdots + (S - A_N)) \ 2 Times \) ... it is not the above formula it? So we got a good \ (O (n) \) approach.

\(Code:\)

#include<cstdio>
#include<vector>
#include<algorithm>
#define rg register
#define ll long long
struct ios{
    template<typename TP>
    inline ios operator >> (TP &x)
    {
        TP f=1;x=0;rg char c=getchar();
        for(;c>'9' || c<'0';c=getchar()) if(c=='-') f=-1;
        for(;c>='0' && c<='9';c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
        x*=f;
        return *this;
    }
    template<typename TP>
    inline ios operator << (TP x)
    {
        char s[66];rg int cnt=0;
        if(!x) putchar('0');
        if(x<0) x=-x,putchar('-');
        while(x) ++cnt,s[cnt]=x%10+'0',x/=10;
        while(cnt) putchar(s[cnt]),--cnt;
        return *this;
    }
    inline ios operator << (char x)
    {
        putchar(x);
        return *this;
    }
}io;
const int N=2e5+5;
std::vector<int>G[N];
const int p=10007;
int n,a,b,w[N],ans,sum;
int main()
{
    io>>n;
    for(rg int i=1;i<n;++i)
    {
        io>>a>>b;
        G[a].push_back(b),G[b].push_back(a);
    }
    for(rg int i=1;i<=n;++i) io>>w[i];
    // for(rg int i=1;i<=n;++i) io<<w[i]<<' ';
    // io<<'\n';
    /*--------------------------以某个节点为中转点的联合权值之和等于权值和的平方减去权值的平方和----------------------*/
    for(rg int i=1;i<=n;++i)
    {
        int max_1=0,max_2=0;
        int he=0,pf=0;
        for(int k=0;k<(int)G[i].size();++k)
        {
            int v=G[i][k];
            // io<<i<<' '<<G[i].size()<<' '<<k<<' '<<v<<'\n';
            if(w[v]>max_1) max_2=max_1,max_1=w[v];
            else if(w[v]>max_2) max_2=w[v];
            he=(he+w[v])%p,pf=(pf+w[v]*w[v])%p;
        }
        he=he*he%p;
        // io<<'h'<<'h'<<max_1<<' '<<max_2<<'\n';
        ans=std::max(ans,max_1*max_2);
        sum=(sum+he-pf+p)%p;//注意he-pf可能为负数
    }
    io<<ans<<' '<<sum;
    return 0;
}

T3 flying bird

Subject to the effect :( First, make sure you know \ (CodeVs-Flappy Bird \) ) for each position you click rising from the distance and do not click on the decline, the position of each pipe. If you can not find through and through, how much is the minimum number of clicks.

obviouslyAs can be seen, this question is \ (DP \) (the optimal solution, relatively large range of data, can not be greedy, except \ (DP \) , really did not practice a)

  • With \ (dp [i] [j ] \) abscissa as \ (I \) height is \ (J \) minimum number of clicks, with $ + \ infty $ impossible to represent this state is reached.
  • The position of each pipeline can not go to other places to go by the rules, pay attention to the birds hit the ceiling not hang, only height \ (0 \) is only linked to, so special about the sentence.

\(Code:\)

#include<cstdio>
#include<algorithm>
#include<cmath>
#define rg register
#define ll long long
#define cg c=getchar()
using namespace std;
struct ios{
    template<typename TP>
    inline ios operator >> (TP &x)
    {
        TP f=1;x=0;rg char cg;
        for(;c>'9' || c<'0';cg) if(c=='-') f=-1;
        for(;c>='0' && c<='9';cg) x=(x<<3)+(x<<1)+(c^'0');
        x*=f;
        return *this;
    }
    template<typename TP>
    inline ios operator << (TP x)
    {
        char s[66];rg int cnt=0;
        if(x<0) x=-x,putchar('-');
        if(!x) putchar('0');
        while(x) s[++cnt]=x%10+'0',x/=10;
        while(cnt) putchar(s[cnt--]);
        return *this;
    }
    inline ios operator << (char s)
    {
        putchar(s);
        return *this;
    }
}io;
const int N=1e4;
const int M=1e3;
const int inf=0x3f3f3f3f;
int n,m,k,cnt=1;
struct node{
    int x,y;
}a[N];
struct Node{
    int pos,L,H;
    inline bool operator < (const Node b) const {
        return pos<b.pos;
    }
}g[N];
int dp[N][M],vis[N][M];
int main()
{
    io>>n>>m>>k;
    for(rg int i=0;i<n;++i) io>>a[i].x>>a[i].y;
    for(rg int i=1;i<=k;++i)
    {
        io>>g[i].pos>>g[i].L>>g[i].H;
        for(int j=1;j<=g[i].L;++j) vis[g[i].pos][j]=1;
        for(int j=g[i].H;j<=m;++j) vis[g[i].pos][j]=1;
    }
    sort(g+1,g+k+1);
    //io<<'h'<<'h'<<'h'<<'\n';
    for(rg int i=1;i<=n;++i)
        for(rg int j=1;j<=m;++j) dp[i][j]=inf;
    for(rg int i=1;i<=n;++i)
    {
    //    io<<'h'<<'h'<<'h'<<'\n';
        int L=1,R=m;
        if(g[cnt].pos==i) L=g[cnt].L+1,R=g[cnt].H-1,++cnt;
        // if(i==5) io<<L<<' '<<R<<'\n';
        int x=a[i-1].x,y=a[i-1].y;
        for(rg int j=L;j<=R;++j)
        {
            if(j==m)
            {
                for(rg int l=1;l<=m;++l)
                {
                    if(!vis[i-1][l])
                    {
                        int w=ceil(1.0*(m-l)/x);
                        if(j==l) w=1;
                        dp[i][j]=min(dp[i][j],dp[i-1][l]+w);
                    }
                }
                continue;
            }
            // if(i==5) io<<j+y<<' '<<y<<'\n';
            if(j+y<=m && !vis[i-1][j+y]) dp[i][j]=min(dp[i][j],dp[i-1][j+y]);
            int w=j/x;
            for(rg int l=1;l<=w;++l)
                if(j-x*l>0 && !vis[i-1][j-x*l])
                    dp[i][j]=min(dp[i][j],dp[i-1][j-x*l]+l);
        }
    //    io<<'h'<<'h'<<'h'<<'\n';
    }
    int ans=inf;
    // for(int i=m;i>=0;--i)
    // // for(int i = 0; i <= n; ++i)
    // {
    //     // for (int j = 0; j <= m; ++j)
    //     for(int j=0;j<=n;++j)
    //     {
    //         if(dp[j][i]==inf) io<<'*'<<' ';
    //         else io<<dp[j][i]<<' ';
    //     }
    //     io<<'\n';
    // }
    for(rg int i=1;i<=m;++i) ans=min(ans,dp[n][i]);
    if(ans==inf)
    {
        io<<0<<'\n';
        for(rg int i=1;i<=k;++i)
        {
            int p=g[i].pos;
            for(rg int j=1;j<=m;++j)
            {
                if(dp[p][j]!=inf) break;
                if(j==m)
                {
                    io<<i-1<<'\n';
                    return 0;
                }
            }
        }
    }
    io<<1<<'\n'<<ans;
    return 0;
}

However, you find that the geese reach the upper bound of \ (O (nm ^ 2) \) The \ (DP \) only water \ (80 \) points. (But when there are leagues \ (80 \) points is also good)
Then how to optimize it?
We found that each bird to rise several times, but only fell once (when not exceed the boundaries guarantee).
Increased many times, is not the equivalent of multiple backpack it?
Then fell once, can be seen as \ (01 \) backpack.
With this idea, we can successfully complexity will \ (O (nm) \) the

\(Code:\)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define rg register
#define ll long long
#define cg c=getchar()
using namespace std;
struct ios{
    template<typename TP>
    inline ios operator >> (TP &x)
    {
        TP f=1;x=0;rg char cg;
        for(;c>'9' || c<'0';cg) if(c=='-') f=-1;
        for(;c>='0' && c<='9';cg) x=(x<<3)+(x<<1)+(c^'0');
        x*=f;
        return *this;
    }
    template<typename TP>
    inline ios operator << (TP x)
    {
        char s[66];rg int cnt=0;
        if(x<0) x=-x,putchar('-');
        if(!x) putchar('0');
        while(x) s[++cnt]=x%10+'0',x/=10;
        while(cnt) putchar(s[cnt--]);
        return *this;
    }
    inline ios operator << (char s)
    {
        putchar(s);
        return *this;
    }
}io;
const int N=1e4+5;
const int M=1e3+5;
const int inf=0x3f3f3f3f;
int n,m,k;
struct node{
    int x,y;
}a[N];
int dp[N][M<<1],vis[N],L[N],R[N];
int main()
{
    // freopen("1.in","r",stdin);
    io>>n>>m>>k;
    for(rg int i=1;i<=n;++i) io>>a[i].x>>a[i].y,L[i]=1,R[i]=m;
    for(rg int i=1;i<=k;++i)
    {
        int a,b,c;io>>a>>b>>c;
        vis[a]=1,L[a]=b+1,R[a]=c-1;
    }
    memset(dp,0x3f,sizeof dp);
    for(rg int i=1;i<=m;++i) dp[0][i]=0;
    for(rg int i=1;i<=n;++i)
    {
        int x=a[i].x,y=a[i].y;
        for(rg int j=x+1;j<=m+x;++j)
            dp[i][j]=min(dp[i-1][j-x]+1,dp[i][j-x]+1);
        for(rg int j=m+1;j<=m+x;++j)
            dp[i][m]=min(dp[i][m],dp[i][j]);
        for(rg int j=1;j+y<=m;++j)
            dp[i][j]=min(dp[i][j],dp[i-1][j+y]);
        // io<<i<<' '<<L<<' '<<R<<'\n';
        for(rg int j=1;j<=L[i]-1;++j) dp[i][j]=inf;
        for(rg int j=R[i]+1;j<=m;++j) dp[i][j]=inf;
    }
    int ans=inf;
    // io<<inf<<'\n';
    // for(int i=m;i>=0;--i)
    // // for(int i = 0; i <= n; ++i)
    // {
    //     // for (int j = 0; j <= m; ++j)
    //     for(int j=0;j<=n;++j)
    //       {
    //         if(dp[j][i]==inf) io<<'*'<<' ';
    //         else io<<dp[j][i]<<' ';
    //     }
    //     io<<'\n';
    // }
    for(rg int i=1;i<=m;++i) ans=min(ans,dp[n][i]);
    if(ans>=inf)
    {
        io<<0<<'\n';
        int i,j;
        for(i=n;i>=1;--i)
        {
            for(j=1;j<=m;++j)
            {
                if(dp[i][j]<inf) break;
            }
            if(j<=m) break;
        }
        ans=0;
        for(int j=1;j<=i;++j)
            if(vis[j]) ++ans;
        io<<ans;
    }
    else io<<1<<'\n'<<ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/p-z-y/p/11720223.html