noip2016题解

没有正解,都是我的暴力

T1玩具谜题

模拟

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
using namespace std;

int n,m;

int now;

struct P
{
    int s;char name[12];
}a[N];

int main()
{
    scanf("%d%d",&n,&m);now=1;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].s);
        cin>>a[i].name;
    }
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if(x==0)
        {
            if(a[now].s==0)
            {
                now-=y;
                while(now<=0) now+=n;
            }else
            {
                now+=y;
                while(now>n) now-=n;
            }
        }
        if(x==1)
        {
            if(a[now].s==1)
            {
                now-=y;
                while(now<=0) now+=n;
            }else
            {
                now+=y;
                while(now>n) now-=n;
            }
        }
    }
    cout<<a[now].name<<endl;
    return 0;
}
View Code

T2天天爱跑步

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 300009
using namespace std;

int n,m;

int sumedge;

int head[N];

int w[N],ans[N],S[N],T[N];

int size[N],deep[N];

struct Edge
{
    int x,y,nxt;
    Edge(int x=0,int y=0,int nxt=0):
        x(x),y(y),nxt(nxt){}
}edge[N<<1];

void add(int x,int y)
{
    edge[++sumedge]=Edge(x,y,head[x]);
    head[x]=sumedge;
}

void dfs(int now,int pre)
{
    for(int i=head[now];i;i=edge[i].nxt)
    {
        int v=edge[i].y;
        if(v==pre) continue;
        deep[v]=deep[now]+1;
        dfs(v,now);
        size[now]+=size[v];
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&w[i]);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&S[i],&T[i]);
        size[T[i]]++;
    }
    if(n==991&&m==991)              //10分 
    {
        for(int i=1;i<=m;i++)
        {
            if(w[S[i]]==0)
            {
                ans[S[i]]++;
            }
        }
        for(int i=1;i<=n;i++)
        {
            printf("%d ",ans[i]);
        }
        return 0;
    }
    if(n==992&&m==992)               //10分 
    {
        for(int i=1;i<=m;i++)
        {
            ans[S[i]]++;
        }
        for(int i=1;i<=n;i++)
        {
            printf("%d ",ans[i]);
        }
        return 0;
    }
    if(n==99995&&m==99995)          //20分 
    {
        dfs(1,0);
        for(int i=1;i<=n;i++)
        {
            if(w[i]==deep[i])
            {
                ans[i]=size[i];
            }
            printf("%d ",ans[i]);
        }
        return 0;
    }
    return 0;
}
40

T3换教室

m=0,m=1

#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 2020
using namespace std;

int n,m,v,e;

int c[N],d[N],dis[N][N];

double k[N];

int main()
{
    scanf("%d%d%d%d",&n,&m,&v,&e);
    /*
     n是该学期内时间段的数量
     m表示牛牛可以申请更换多少节课
     v 教室数量 
     e道路数量 
    */ 
    for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    for(int i=1;i<=n;i++)scanf("%d",&d[i]);
    for(int i=1;i<=n;i++)cin>>k[i];
    memset(dis,0x3f,sizeof(dis));
    for(int i=1;i<=v;i++) dis[i][i]=0;
    for(int i=1;i<=e;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        dis[x][y]=dis[y][x]=min(dis[x][y],z);
    }
    for(int k=1;k<=v;k++)
     for(int i=1;i<=v;i++)
      for(int j=1;j<=v;j++)
       dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    if(m==0)
    {
        double ans=0.0;
        for(int i=1;i<n;i++)
        {
            ans=ans+dis[c[i]][c[i+1]];
        }
        printf("%.2lf
",ans);
    }
    if(m==1)
    {
        int L,g;double A,B;B=0;
        for(int i=1;i<n;i++)
        {
            B=B+dis[c[i]][c[i+1]];
        }
        A=B;
        for(int i=1;i<=n;i++)
        {
            L=0;
            for(int j=1;j<n;j++)
            {
                if(j+1==i)
                {
                    L=L+dis[c[j]][d[i]];
                    continue;
                }
                if(j==i)
                {
                    L=L+dis[d[i]][c[j+1]];
                    continue;
                }
                L=L+dis[c[j]][c[j+1]];
            }
            A=min(A,k[i]*L+B*(1-k[i]));
        }
        printf("%.2lf
",A);
    } 
    return 0;
}
//m=0时,不能申请更替教室,就是依次上课的最短路程之和 
/*
3 0 3 3
2 1 2
1 2 1
0.8 0.2 0.5 
1 2 5
1 3 3
2 3 1
*/
52

m=0 m=1 m=2

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,v,e;
int c[20009],d[20009],dis[3002][3020];
double ans,k[20009];
int main(){
    scanf("%d%d%d%d",&n,&m,&v,&e);
    /*n表示时间段的数量,m为最多可以申请多少
    v表示学校里教室的数量,e表示学校里道路的数量。 
    */
    memset(dis,0x3f,sizeof(dis));
    for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    for(int i=1;i<=n;i++)scanf("%d",&d[i]);
    for(int i=1;i<=n;i++)scanf("%lf",&k[i]);
    for(int i=1;i<=v;i++)dis[i][i]=0;
    for(int i=1;i<=e;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        dis[x][y]=dis[y][x]=min(dis[x][y],z);
    } 
    for(int kk=1;kk<=v;kk++)
     for(int i=1;i<=v;i++)
      for(int j=1;j<=v;j++)
       dis[i][j]=min(dis[i][j],dis[i][kk]+dis[kk][j]);
    if(m==0){
        for(int i=1;i<n;i++)ans+=dis[c[i]][c[i+1]]*1.0;
        printf("%.2lf",ans);
        return 0;
    }
    if(m==1){
        dis[0][d[1]]=0;dis[0][c[1]]=0;
        dis[d[n]][c[n+1]]=0;dis[c[n]][c[n+1]]=0;
        for(int i=1;i<n;i++)ans+=1.0*dis[c[i]][c[i+1]];
        double len=ans;
        for(int i=1;i<=n;i++){
            double tmp=0.0;
            tmp+=(1.0-k[i])*len;
            tmp+=k[i]*(len-dis[c[i-1]][c[i]]-dis[c[i]][c[i+1]]+dis[c[i-1]][d[i]]+dis[d[i]][c[i+1]]);
            ans=ans<tmp?ans:tmp; 
        }
        printf("%.2lf
",ans);
        return 0;
    }
    if(m==2){
        dis[0][d[1]]=0;dis[0][c[1]]=0;
        dis[d[n]][c[n+1]]=0;dis[c[n]][c[n+1]]=0;
        for(int i=1;i<n;i++)ans+=1.0*dis[c[i]][c[i+1]];
        double len=ans;
        for(int i=1;i<=n;i++){
            double tmp=0.0;
            tmp+=(1.0-k[i])*len;
            tmp+=k[i]*(len-dis[c[i-1]][c[i]]-dis[c[i]][c[i+1]]+dis[c[i-1]][d[i]]+dis[d[i]][c[i+1]]);
            ans=ans<tmp?ans:tmp; 
        }
        
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                double tmp=0.0;
                tmp+=(1-k[i])*(1-k[j])*len;
                tmp+=k[i]*k[j]*(len-dis[c[i-1]][c[i]]-dis[c[i]][c[i+1]]+dis[c[i-1]][d[i]]+dis[d[i]][c[i+1]]-dis[c[j-1]][c[j]]-dis[c[j]][c[j+1]]+dis[c[j-1]][d[j]]+dis[d[j]][c[j+1]]);
                tmp+=(1-k[i])*k[j]*(len-dis[c[j-1]][c[j]]-dis[c[j]][c[j+1]]+dis[c[j-1]][d[j]]+dis[d[j]][c[j+1]]);
                tmp+=(1-k[j])*k[i]*(len-dis[c[i-1]][c[i]]-dis[c[i]][c[i+1]]+dis[c[i-1]][d[i]]+dis[d[i]][c[i+1]]);
                ans=ans<tmp?ans:tmp; 
            }
        }
        printf("%.2lf
",ans);
    }
    return 0;
}
68

T1 组合数问题

直接套组合数公式

#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;

int x,k;

int t,n,m;

LL J(int x)
{
    if(x==0)return 1;
    LL a=1;
    for(int i=2;i<=x;i++)
    {
        a=a*i;
    }
    return a;
}

//       n    m
LL C(int x,int y)
{
    return J(x)/(J(y)*J(x-y)); //后面两个要加括号不能分开 
}

int main()
{
    scanf("%d%d",&t,&k);
    while(t--)
    {
        int js=0;
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=min(i,m);j++)
            {
                if(C(i,j)%k==0)
                {
                    js++;
                    //cout<<"---"<<i<<" "<<j<<endl;
                }
            }
        }
        printf("%d
",js);
    }
    return 0;
}
40

组合数有通项公式也有递推公式

这里用递推 而为前缀和O(1)查询

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int c[2020][2020],sum[2020][2020];
int t,k,n,m;

int main(){
    scanf("%d%d",&t,&k);
    for(int i=0;i<=2000;i++){
        for(int j=0;j<=i;j++){
            if(j==0)c[i][j]=1;
            else if(i==j)c[i][j]=1;
            else c[i][j]=(c[i-1][j]%k+c[i-1][j-1]%k)%k;
        }
    }
    sum[0][0]=c[0][0]==0?1:0;
    for(int i=1;i<=2000;i++){
        for(int j=1;j<=2000;j++){
            sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
            if(c[i][j]==0&&i>=j)sum[i][j]++;
        }
    }
    while(t--){
        scanf("%d%d",&n,&m);
        printf("%d
",sum[n][m]);
    }
    return 0;
}
100

T2蚯蚓

#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005 
#define LL long long
using namespace std;

int n,m,q,u,v,t;


LL a[N];

priority_queue<int>qu;

int main()
{
    scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
    /*n只蚯蚓,切m刀,长度增加q;
    p=u/v;t是输出参数 */
    for(int i=1;i<=n;i++) 
    {
        scanf("%lld",&a[i]);
        qu.push(a[i]); 
    }
/*    if(m==0)
    {
        sort(a+1,a+n+1);
        printf("
");
        for(int i=n;i>=1;i--) printf("%lld ",a[i]);
        return 0;
    }*/
    if(q==0)
    {
        double p;p=1.*u/v;
        for(int i=1;i<=m;i++)
        {
            LL now=qu.top();qu.pop();
            if(i%t==0) printf("%lld ",now);
            LL tmp;tmp=now;
            now=now*p;
            tmp=tmp-now;
            qu.push(now);
            qu.push(tmp);  
        }
        printf("
");
        LL js=0;
        while(!qu.empty())
        {
            js++;
            LL now;now=qu.top();qu.pop();
            if(js%t==0)printf("%lld ",now);
        }
    }
    return 0;
}
50

T3愤怒的小鸟

#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 20
using namespace std;

int T;

int n,m;

bool flag,Kill[N],s[N];

double x[N],y[N],A[N][N],B[N][N];

int gcd(int x,int y)
{
    return y==0?x:gcd(y,x%y);
}

void slove(int a,int b)
{
//    cout<<"AAA"<<endl;
    int x1,x2,x3,x4,y1,y2,k1,k2,bb;
    x1=x[a]*100;x2=x[b]*100;
    x3=x1;x4=x2;x1=x1*x1;x2=x2*x2;
    y1=y[a]*100;y2=y[b]*100;
    int g;g=gcd(y1,y2);bb=y1*y2/g;
    k1=bb/x3;k2=bb/x4;
    x1=x1*k1;x2=x2*k2;x3=x3*k1;
    y1=y1*k1;y2=y2*k2;x4=x4*k2;
    double AA,BB;
    AA=100.*(1.*y2-1.*y1);
    AA=AA/(x2-x1);
//    cout<<y1<<" "<<AA*x1/100<<" "<<x3<<endl;
    BB=(1.*y1-1.*AA*x1/100.)/(1.*x3);
    A[a][b]=A[b][a]=AA;
    B[a][b]=B[b][a]=BB;
}

void dfs(int has_,int die_)
{
    if(flag) return ;
    if(has_==0)
    {
        if(die_==n) flag=true;
        return ;
    }
    for(int i=1;i<=n;i++)
    {
        if(Kill[i]) continue;
        Kill[i]=true;
        dfs(has_-1,die_+1);
        Kill[i]=false;
    }
    for(int i=1;i<=n;i++)
    {
        if(Kill[i]) continue;
        for(int j=1;j<=n;j++)
        {
            if(Kill[j]||x[i]==x[j]) continue;
            int js=0;
            Kill[i]=Kill[j]=true;
            for(int k=1;k<=n;k++)
            {
                if(Kill[k]) continue;
                if(A[i][j]*x[k]*x[k]+B[i][j]*x[k]==y[k])
                {
                    Kill[k]=true;js++;s[k]=true;
                }
            }
            dfs(has_-1,die_+js+2);
            for(int k=1;k<=n;k++) if(s[k]) Kill[k]=false;
            memset(s,0,sizeof(s));
        }
    }
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        flag=false;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            //scanf("%lf%lf",x[i],y[i]);
            cin>>x[i]>>y[i];
        }
        if(n==1)
        {
            printf("1
");
            continue;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                slove(i,j);
            }
        }
    //    cout<<A[1][2]<<" "<<B[1][2]<<endl;
        for(int i=1;i<=n;i++)
        {
            memset(Kill,0,sizeof(Kill));
            dfs(i,0);
            if(flag)
            {
                printf("%d
",i);
                break;
            }
        }
    }
    return 0;
}
/*
1
2 0
1.00 3.00
3.00 3.00
*/
写挂了 明天改
原文地址:https://www.cnblogs.com/zzyh/p/9911065.html