noip2017题解

没有正解,都是我的暴力

T1

枚举两个金币个数

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

int a,b,ans;
int c[10000];

int main()
{  
    scanf("%d%d",&a,&b);
    if(a>b)swap(a,b);
    for(int i=0;i<100;i++)
    {
        for(int j=0;j<=100;j++)
        {
            c[a*i+b*j]=true;
        }
    }
    int js=0;
    for(int i=0;i<=a*b;i++)
    {
        if(c[i])js=0;
        else ans=i,js++;
    }
    cout<<ans<<endl;
    return 0;
}
View Code

T2

以下是我打的部分分代码

队列模拟做标记

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

int T;

int js,L;

bool flag;

char fzd[10];

char a[10],b[10],c[10],d[10],e[10],f[10];

int get()
{
    if(fzd[2]=='1') return 0;
    int x=0,Len=strlen(fzd);
    for(int i=4; i<Len; i++)
    {
        if(fzd[i]<'0'||fzd[i]>'9') break;
        x=x*10+fzd[i]-'0';
    }
    return x;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&L);
        cin>>fzd;
        flag=true;
        js=0;
        int p;
        p=get();//p是给的复杂度
        for(int i=1; i<=L; i++)
        {
            cin>>a;
            if(a[0]=='F')
            {
                cin>>b>>c>>d;
                int cc,dd;
                if(c[0]=='n') cc=1000;
                else cc=c[0]-'0';
                if(d[0]=='n') dd=1000;
                else dd=d[0]-'0';
                if(dd-cc>=100&&flag)js++;
            }
        }
        if(js==p) printf("Yes
");
        else printf("No
");
    }
    return 0;
}
27
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int T;

int t,flag,ans,L;

int s[30],q[120];

char fzd[10];

char a[10],b[10],c[10],d[10],e[10];

int get()
{
    if(fzd[2]=='1') return 0;
    int x=0,Len=strlen(fzd);
    for(int i=4;i<Len;i++)
    {
        if(fzd[i]<'0'||fzd[i]>'9') break;
        x=x*10+fzd[i]-'0';
    }
    return x;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&L); cin>>fzd;
        int p,js;p=get(); ans=0;flag=0;t=0;
        for(int i=1;i<=L;i++)
        {
            cin>>a;
            if(a[0]=='F')
            {
                cin>>b>>c>>d;
                int cc=0,dd=0;
                if(c[0]=='n') cc=10000; 
                else
                {
                    int lc;lc=strlen(c);
                    for(int j=0;j<lc;j++) cc=cc*10+c[j]-'0';
                }
                if(d[0]=='n') dd=10000; 
                else
                {
                    int ld;ld=strlen(d);
                    for(int j=0;j<ld;j++) dd=dd*10+d[j]-'0';
                }
                if(cc>dd) flag++,s[b[0]-'a']=true;
                if(dd>=cc&&!flag)
                {
                    if(dd-cc>=100) q[++t]=b[0]-'a';
                    ans=max(ans,t);
                }
            }
            if(a[0]=='E')
            {
                if(s[q[t]]) s[q[t]]=0,flag--;
                t--;
            }
        }
        if(ans==p) printf("Yes
");
        else printf("No
");
    }
    return 0;
}
45

然而还没有a

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

int L,T;

int t,f,flag,ans;

int q[120],s[120],vis[30],in[30];

char fzd[10];

char a[10],b[10],c[10],d[10],e[10];

int get()
{
    if(fzd[2]=='1') return 0;
    int x=0,Len=strlen(fzd);
    for(int i=4;i<Len;i++)
    {
        if(fzd[i]<'0'||fzd[i]>'9') break;
        x=x*10+fzd[i]-'0';
    }
    return x;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&L);cin>>fzd;
        int p,js;p=get();ans=js=0;f=t=0;
        memset(vis,0,sizeof(vis));
        memset(in,0,sizeof(in));
        for(int i=1;i<=L;i++)
        {
            cin>>a;
            if(a[0]=='F')
            {
                cin>>b>>c>>d;
                if(vis[b[0]-'a']) 
                {
                    f=true;
                    break;
                }
                vis[b[0]-'a']=true;
                int cc,dd;cc=dd=0;
                if(c[0]=='n') cc=10000;
                else
                {
                    int lc=strlen(c);
                    for(int j=0;j<lc;j++) cc=cc*10+c[j]-'0';
                }
                if(d[0]=='n') dd=10000;
                else
                {
                    int ld=strlen(d);
                    for(int j=0;j<ld;j++) dd=dd*10+d[j]-'0';
                }
                q[++t]=b[0]-'a';
                if(cc>dd) s[b[0]-'a']=true,flag++;
                if(cc<=dd&&!flag)
                {    
                    if(dd-cc>=100) in[b[0]-'a']=true,js++;
                    ans=max(ans,js);
                }
            }
            if(a[0]=='E')
            {
                vis[q[t]]=false;if(s[q[t]]) s[q[t]]=0,flag--;
                if(in[q[t]]) in[q[t]]=false,js--;
                t--;
            }
        }    
        if(t||f) 
        {
            printf("ERR
"); continue;
        }
        if(ans==p) printf("Yes
");
        else printf("No
");
    }
    return 0;
}
91

T3

spfa算出最短路,dfs找最短路和最短路+k之间的路径的条数

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

int T,L,R,Ans;

int n,m,k,p;

int sumedge;

int head[N],vis[N],dis[N];

queue<int>q;

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

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

void clear()
{
    memset(vis,0,sizeof(vis));
    memset(head,0,sizeof(head));
    sumedge=0;
}

void spfa()
{
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    while(!q.empty())q.pop();
    dis[1]=0;vis[1]=true;q.push(1);
    while(!q.empty())
    {
        int now=q.front();q.pop();vis[now]=false;
        for(int i=head[now];i;i=edge[i].nxt)
        {
            int v=edge[i].y;
            if(dis[v]>dis[now]+edge[i].z)
            {
                dis[v]=dis[now]+edge[i].z;
                if(!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
}


void dfs(int now,int g)
{
    if(g>R) return;
    if(now==n)
    {
        Ans=(Ans%p+1%p)%p;
    }
    for(int i=head[now];i;i=edge[i].nxt)
    {
        int v=edge[i].y;
        dfs(v,g+edge[i].z);
    }
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d",&n,&m,&k,&p);
        clear();Ans=0;
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        spfa();L=dis[n];R=dis[n]+k;
        dfs(1,0);
        printf("%d
",Ans);
    }
    return 0;
}
30

T1

Int相乘能爆,要开long long

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

int T;

LL n,h,r;

int flag;

int vis[N];

queue<int>q;

struct B
{
    LL x,y,z; //忘开LL 
}a[N];

inline 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;
}

bool cmp(B a,B b)
{
    return a.z<b.z;
}

double dis(int x,int y)
{
    LL X;X=(a[x].x-a[y].x)*(a[x].x-a[y].x);
    LL Y;Y=(a[x].y-a[y].y)*(a[x].y-a[y].y);
    LL Z;Z=(a[x].z-a[y].z)*(a[x].z-a[y].z);
    return sqrt(X+Y+Z);
}

void BFS(int now)
{
    memset(vis,0,sizeof(vis));
    while(!q.empty()) q.pop();
    vis[now]=true;q.push(now);
    while(!q.empty())
    {
        int now=q.front();q.pop();
        if(a[now].z+r>=h)
        {
            flag=true;
            break;
        }
        for(int i=1;i<=n;i++)
        {
            if(vis[i]) continue;
            if(dis(i,now)>1.*2*r) continue;
            q.push(i);vis[i]=true;
        }
    }
}

int main()
{
    T=read();
    while(T--)
    {
        flag=false;
        n=read();cin>>h>>r;
        for(int i=1;i<=n;i++)
        {
            a[i].x=read();a[i].y=read();a[i].z=read();
        }
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            if(a[i].z-r<=0)BFS(i);
            if(flag)
            {
                printf("Yes
");
                break;
            }
        }
        if(!flag) printf("No
");
    }
    return 0;
}
100

 T2

20%是树 枚举起点+dfs

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

int n,m,ans,res;

int d[10][10];

void dfs(int now,int sc,int pre)
{
    for(int i=1;i<=n;i++)
    {
        if(i==now||i==pre||d[now][i]==0) continue;
        ans=ans+d[now][i]*sc;
        dfs(i,sc+1,now);
    }
    return ;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        d[x][y]=d[y][x]=z;
    }
    res=1000000000;
    for(int i=1;i<=n;i++)
    {
        ans=0;
        dfs(i,1,0);
        res=min(res,ans);
    }
    printf("%d
",res);
    return 0;
} 
20

70% dfs。

枚举起点和每次要开拓的边。

枚举边就枚举要开拓的点,再枚举这个点有哪个点开拓来。

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

int n,m;

int tmp,ans;

int d[12][12],Len[12];

void dfs(int now,int scr)
{
    if(now==n)
    {
        tmp=min(tmp,scr);
        return ;
    }
    if(scr>=ans) return ;
    for(int i=1;i<=n;i++)
    {
        if(Len[i]) continue;
        for(int j=1;j<=n;j++)
        {
            if(d[i][j]==2147483640||Len[j]==0) continue;
            Len[i]=Len[j]+1;
            dfs(now+1,scr+Len[j]*d[i][j]);
            Len[i]=0;
        }
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i==j) continue;
            d[i][j]=2147483640;
        }
    }
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        d[x][y]=d[y][x]=min(d[x][y],z);
    }
    ans=2147483645;
    for(int i=1;i<=n;i++)
    {
        memset(Len,0,sizeof(Len));
        Len[i]=1;tmp=2147483640;
        dfs(1,0);
        ans=min(ans,tmp);
    }
    cout<<ans<<endl;
    return 0;
}
70

T3

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

int n,m,q;

int a[3002][3003];

int qx[30004],qy[30004];

int main()
{
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=q;i++) scanf("%d%d",&qx[i],&qy[i]);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            a[i][j]=(i-1)*m+j;
        }
    }
    for(int i=1;i<=q;i++)
    {
        int x=qx[i],y=qy[i];
        int tmp=a[x][y];
        printf("%d
",tmp);
        for(int j=y;j<m;j++) a[x][j]=a[x][j+1];
        for(int j=x;j<n;j++) a[j][m]=a[j+1][m];
        a[n][m]=tmp;
    }
    return 0;
}
30
原文地址:https://www.cnblogs.com/zzyh/p/9905410.html